Skip to content

v1.2.5 · StartOS package 1.2.5:0

Choose a tag to compare

@github-actions github-actions released this 06 Oct 18:21
b1eff6d

Added

  • A preview of the 2026 tax forms. The IRS's final 2026 Form 8949 and
    Schedule D usually come out in December or January; until then Reports
    offers 2026 as "2026 – IRS draft (preview, not for filing)", filled from
    the IRS's draft forms, which say "DRAFT — DO NOT FILE" on every page,
    with a warning not to file them. On January 1, 2027 the preview stops by
    itself, so nobody files a draft from a version they never updated: the
    final forms come in an update, which replaces it. Reports now also says,
    for a year without forms yet, that they come in an update (#53).
  • A full test ledger on any server, and 2026's forms from the IRS
    drafts, for testing only.
    scripts/seed_ledger.py loads 103
    transactions (2023 to 2026) into a running BitcoinTX over its API: every
    year has every kind of transaction, and every report has entries in each
    part, every Form 8949 box of 2024 (A–F), 2025 and 2026 (G–L) included, in
    any tax timezone.
    Every USD value a price lookup would fill is given, so it loads with the
    price source Off. It refuses a ledger that has
    transactions and the Mac app's address. On a test install,
    python -m backend.cli install-draft-forms puts the IRS's draft 2026
    Form 8949 and Schedule D in the data folder; Reports then offers 2026,
    labelled as the IRS draft, and prints them with the IRS's
    "DRAFT — DO NOT FILE" on every page. The drafts are checked like a final
    form (year, marking, every field the app writes), and are ignored once a
    version has that year's final forms. The StartOS test lab's vmtest seed uses both, so
    every report can be clicked through on the VM without the owner's real
    ledger (#51).

Changed

  • A professional Complete Tax Report. Redesigned from the ground up,
    with the same figures:
    • a cover with the year's key figures (net capital gain, income, bitcoin
      held and its value at year end), how the report was made (FIFO per
      account, tax timezone, prices, when it was generated) and contents
      with page numbers;
    • a one-page summary: gains and losses by term, each Form 8949 box with
      its Schedule D line and totals (the same as the IRS forms BitcoinTX
      fills), income by source, and holdings on January 1 and December 31;
    • the detail, each table with a totals row and its heading repeated on
      every page it runs onto: every disposal (with its kind, Form 8949 box
      and term, in the IRS column order: proceeds, cost basis, gain), income,
      gifts, donations and lost coins, and the holdings at year end by
      account and lot by lot (they listed every lot as a "balance" before,
      with the same price note on each row);
    • losses in parentheses as on the IRS forms, a running header and "Page X
      of Y" on every page, and the notes at the end.
      Fixed on the way: the number of disposals sat in the Short Term column
      though it counted both; two column headings overlapped; and a table that
      ran onto another page lost its heading there.
  • The Transaction History PDF fits the page. Its table was wider than
    the page (columns were cut off). It is now landscape, in the same look,
    with dates in the tax timezone, each type with its source or purpose
    ("Withdrawal (Spent)"), amounts and fees with their currency, and page
    numbers. Reports now offers it: with Transaction History selected,
    Format is CSV spreadsheet (as before) or PDF; before, the PDF could only
    be had through the API. The CSV is unchanged.

Fixed

  • The Complete Tax Report no longer has an "Expenses" section. It
    listed withdrawals with the purpose "Expenses", which the app's forms
    never offered (a BTC withdrawal is Spent, Gift, Donation or Lost), so it
    almost always said "No transactions". Rows that reached it: a BTC
    "Expenses" row from an old ledger, and a cash withdrawal sent by API or
    CSV with that purpose, which it showed as BTC.
    Spending is in the capital gains section, as before, and so is a BTC
    "Expenses" row an old ledger still has. No figure changes (#58).
  • The Mac app no longer carries the test files. It bundled all of
    backend/, its tests and test ledgers included (harmless, never used);
    now it leaves out backend/tests/ and what a dev run leaves in the
    build's checkout (a database, its backups, the session key, the setup
    code). Docker and StartOS never had the tests; their build now also
    ignores those dev files. Release builds start from a clean checkout and
    were never affected.
  • On a phone, the transaction panel can be closed. Up to 460 px wide the
    Add or Edit Transaction panel covers the whole page, so there was nothing
    outside it to tap and no Escape key: Save was the only button, and the
    phone's Back button left the page and dropped what was typed without
    asking. A close button (✕) in the panel's header now closes it, on every
    screen, like a click outside: at once when nothing was changed, else after
    "Discard changes?". Found by the full test run of 1.2.4.

StartOS package

  • Package 1.2.5:0. Release notes in five languages; 1.2.4:1's
    one-time cleanup of the retired Show Credentials task moved to its own
    version file, so installs from before it still get it.
  • Start9's review, taken back (package 1.2.4:1, on Community Beta).
    Start9 reviewed the package on their fork
    (Start9-Community/BTCTX-StartOS#1) and merged it on 2026-10-05; startos/
    now has it as they wrote it. One Set Login Credentials action
    replaces Show Credentials and Reset Login Credentials: it makes a new
    random password and shows it once, at install (a critical task; install
    no longer creates the database) and whenever the owner has lost it, only
    while the service is stopped. A login StartOS already made stays; an
    older install whose password was set in the app gets the critical task,
    and running it replaces that login. The update clears any leftover Show
    Credentials task. The package repository is now Start9's fork; their
    workflows and template updates came too. Our docs, comments, the agent
    release tests and the box test name the new action (#29).

Development

  • The Start9 check survives squash merges. scripts/start9-pull.sh --apply records the Start9 commit it took in scripts/start9-taken
    (committed with the take-back); the release's check then counts only
    what Start9 changed since. Before, it looked for the take-back commit in
    the history, which GitHub's squash merge of #48 removed: the 1.2.5
    release would have stopped at its first step. Set to Start9's 8c030d8,
    the review #48 took.
  • How changes flow, on one page. docs/HOW-CHANGES-FLOW.md maps the
    whole path in plain steps: an everyday change, a release, sending it to
    Start9, taking Start9's own changes back, and keeping this computer and
    GitHub the same. Written for the owner and every AI session; AGENTS.md
    points to it.
  • An issue for each yearly IRS forms step. The weekly IRS forms watch
    now runs all year and opens an issue (label claude) when the IRS
    publishes the next year's draft forms or revises them (ship them as the
    preview) and when it publishes the final forms (add them, in a release).
    Before, it only ran November to March and only failed, with an email, for
    the final forms (scripts/irs_new_year.py --due).
  • One command says whether everything is on GitHub. make sync-check
    (scripts/sync-check.sh) fetches, brings local main and develop down
    when they're only behind, and lists anything that exists only on this
    computer: work not committed in any working folder, branches with
    commits GitHub doesn't have (a merged pull request counts as on GitHub),
    stashes. It ends with IN SYNC or NOT IN SYNC. --tidy also deletes the
    local branches already on GitHub. Every session runs it at its start and
    end, and ends its last message to the owner with "Git: in sync" or what
    is only here (owner's request).
  • The mirror sync builds on Start9's fork.
    scripts/sync-startos-mirror.sh first fast-forwards the mirror's main
    to Start9's fork (or, if the two have diverged, records it as merged,
    keeping startos/), so each pull request to Start9 shows only our
    changes, not theirs undone. It runs start9-pull.sh --check first, also
    for a docs-only sync by hand, and stops if startos/ lacks theirs.
    The check (also the release's first step) now accepts their changes
    taken in a commit since our last sync and edited afterwards; before, our
    edits to two lines Start9 had rewritten would have stopped the next
    release (the release's mirror step now fetches the whole history for
    it). It also passes when Start9's branch is already in the mirror's
    history: what differs then is ours, waiting for them to merge. And it
    now stops, instead of warning, when Start9 changed their fork while a
    pull request of ours is open there: theirs can't be told from ours then,
    and a sync could record their commits without their content.
    startos/'s UPDATING.md, TODO.md and AGENTS.md now say that develop takes pull requests and that to-dos
    are issues (#29).
  • What to do when a dependency update breaks something.
    docs/MAINTENANCE.md now says that an update to the app's or the Mac
    app's Python packages or to the GitHub Actions merges only after the Mac
    build has passed (it isn't
    one of the required checks), that updates which could move a tax figure
    get the before-and-after comparison, how a breaking update is fixed or
    skipped (an ignore rule, a "Deferred upgrades" row and an issue), and
    how a skipped one is taken later.
  • Comments tidied where the linters don't look. The Dockerfile,
    Makefile and scripts/backup-db.sh lost their banners and the comments
    that only restated the next line; the ones left say why. No change in
    behaviour.
  • Everything we name to build with is pinned exactly. The Docker base
    images are pinned by digest and the GitHub Actions by commit (a tag can be
    moved later; the publishing step for the AI connector followed a branch),
    the Mac app's build tools and anyio by version; Dependabot now also
    proposes updates for desktop/ and the base images (the Dockerfile lost
    its indentation, which hid its FROM lines from Dependabot). The packages
    those pull in themselves aren't locked yet (#37). The AI connector
    keeps version ranges, now capped below the next major version of httpx
    and pydantic. The rules are in docs/MAINTENANCE.md, "Updating a
    dependency".
  • Every Python package that ships is locked, with its hash. Each shipped
    requirements file is now a requirements.in (what we name, pinned) with a
    lock beside it, requirements.txt, made by make lock (uv pip compile): every package, the indirect ones too (32 of them were pinned
    nowhere and resolved at build time), at a fixed version with its hashes,
    for Linux (both chip types), macOS and Python 3.10 and up. The Docker
    image installs its lock with --require-hashes and ready-built wheels
    only; the Mac app installs the backend's and desktop/'s locks the same
    way, and builds its one source-only package with the locked setuptools;
    the connector's PyPI build uses a lock of build and setuptools
    (.github/release-tools/) and no longer fetches them unpinned. The Mac
    build no longer upgrades pip or installs wheel, and CI's container
    smoke test installs the lock rather than an unpinned httpx. Dependabot
    keeps the locks current (uv entries); the dependency audit now covers
    all three locks, on Linux and macOS. test_pinning.py checks that each
    lock has every hash and matches its pins, and that whatever ships installs
    with --require-hashes. The indirect packages are refreshed once a month
    (make lock LOCK_ARGS=--upgrade), when the first Monday's weekly check
    reports newer versions (#37).
  • The pre-push check can't break the repository any more. Run from a
    worktree, git hands the hook GIT_DIR; the tests that build throwaway
    repositories inherited it, and their git init set core.bare = true in
    the shared .git/config, so git refused to work in every checkout until
    it was set back. The hook now unsets those variables first (git's advice
    for hooks), and a test keeps that line there.
  • The weekly StartOS check also watches start-cli. Besides a newer
    @start9labs/start-sdk on npm, startos-sdk-check.yml opens an issue
    when Start9 releases a newer start-cli (the tool that packs btctx.s9pk)
    than CI's START_CLI_VERSION. Each issue links the release notes and
    says to look at Start9's fork first, since Start9 may send the bump
    there themselves.
  • One rules file and one to-do list for every AI. The rules moved
    from CLAUDE.md to AGENTS.md, the file other AI tools read too
    (CLAUDE.md now only points to it, which a test checks); it now says who
    does what (the owner decides, Claude Code develops, Grok brainstorms) and where each kind of information lives. To-dos are GitHub
    issues, labelled claude, owner, ask-grok or start9 (the workflows
    label theirs), instead of docs/temp/TODO.md: its open items went to
    #29–#32 (checking that start9-pull.sh --fork finds Start9's fork was
    done), the roadmap's two specific to-dos to #38 and #39, and
    test_todo_lists.py keeps a to-do file from coming back.
  • Every change arrives by reviewed pull request. develop takes changes
    only by pull request (GitHub rulesets now protect main and develop),
    from .github/pull_request_template.md. Each one is reviewed by a fresh
    Claude agent before it merges, as thoroughly as the change needs. Claude
    merges once the required checks pass and nothing is open, except a change
    in tax figures or what the app computes, the database, the StartOS
    package or anything that reaches Start9, and releases, which wait for the
    owner. The pre-push hook now fast-forwards main only to GitHub's
    develop, and scripts/start9-pull.sh --apply runs on a branch for a
    pull request.
  • Sessions start and end at one pinned issue. #41, "Where we are", says
    what's in flight and what's next; each session reads it first and rewrites
    it last (AGENTS.md, "Starting a session"). Reviewed pull requests now
    merge through GitHub's auto-merge once the required checks pass, and a
    branch behind develop is updated by merging develop in, not rebasing.
  • AGENTS.md says what's at stake and how Start9 works. Two new
    sections: the owner's real tax records and ledger, other people's
    installs, privacy; and Start9's fork, Community Beta, promotion, and their
    own changes coming back.

Downloads

  • StartOS: btctx.s9pk, package 1.2.5:0. In StartOS, open Sideload and upload it; installs of earlier versions update in place.
  • macOS: BitcoinTX-macOS.dmg (or the .zip). The app is not signed by Apple: the first time, right-click (Control-click) BitcoinTX in Applications and choose Open; on macOS 15 or later, open it once, then go to System Settings > Privacy & Security and click Open Anyway.
  • Docker: ghcr.io/digimonk73/btctx-mcp:v1.2.5 (amd64 and arm64).
  • AI connector: uvx btctx-mcp==1.2.5 (PyPI); Settings → Connect an AI Assistant has it ready to paste.