• admin released this 2026-04-23 11:47:02 -06:00 | 0 commits to main since this release

    Release v2.9.12 (aba935c)

    Downloads
  • admin released this 2026-04-23 10:54:24 -06:00 | 1 commits to main since this release

    Release v2.9.11 (4ccc433)

    Downloads
  • admin released this 2026-04-16 20:55:15 -06:00 | 3 commits to main since this release

    Release v2.9.10 (6d562da)

    Downloads
  • admin released this 2026-04-16 15:17:54 -06:00 | 8 commits to main since this release

    Install flow follow-up — extract preservation + release drift protection

    Two small but real polish items landed right after v2.9.8 based on friction observed during the v2.9.8 end-to-end test. Both commits are scripts-only; no image rebuild.

    Upgrade notes: Safe upgrade. The behaviour changes only manifest in failure/build paths — happy-path installs are identical to v2.9.8.


    Patch 1 — scripts/install.sh preserves extract on config-wizard failure

    Commit: 20f4bcd3

    Previously, when config.sh could not start (classic case: curl | ssh bash over non-interactive SSH failing at /dev/tty), the cleanup trap removed $INSTALL_DIR because .env hadn't been written yet. The 15 MB tarball had already extracted cleanly — but the user was forced to re-download to retry on a console.

    New EXTRACT_COMPLETE state flag: the trap now distinguishes "extract OK, wizard didn't run" from "extraction itself failed". First case preserves the dir and prints a resumption hint:

    [INFO]  Tarball extracted to /tmp/test-install-dir — preserving.
    [INFO]  To finish setup on an interactive console:
               cd /tmp/test-install-dir && bash config.sh
    [ERROR] Configuration wizard could not run (likely no TTY available).
    

    The user can then cd into the preserved dir and complete setup on a real console, zero re-download.


    Patch 2 — scripts/build-release.sh whitelist parity check

    Commit: 5d497b79

    During the v2.9.8 sprint we added three scripts (pangolin-teardown.sh, ccp-deregister.sh, validate-env.sh) and had to manually remember to add each to build-release.sh's shipping whitelist. Forgetting is silent — the script just doesn't ship, breaking the release in subtle ways.

    Replaced the implicit for-loop with two explicit arrays and a pre-build assertion:

    RUNTIME_SCRIPTS=(...)     # ship in tarball
    DEV_ONLY_SCRIPTS=(...)    # stays on dev/build machines
    

    Every scripts/*.sh must be classified as one or the other. An unclassified script aborts the build with a clear error naming the file, so the next sprint can't silently ship a broken tarball.

    Side-effect fixes from this audit:

    • register-with-ccp.sh is now shipped (was only in source, needed for retrofitting CCP onto existing installs)
    • update-env.sh is now shipped (safe .env updater used by upgrade flows)

    Release tarballs now contain 20 scripts (up from 17 in v2.9.8).


    Verified end-to-end

    On marcelle:

    • curl -fsSL .../install.sh | bash -s -- --dir /tmp/test-install-dir --version v2.9.9 over non-TTY SSH → extract preserved, resumption hint printed, /tmp/test-install-dir/ retained
    • ./scripts/build-release.sh --dry-run with a hypothetical unclassified scripts/*.sh → aborts with named error
    • ./scripts/build-release.sh --tag v2.9.9 --upload → succeeds on fresh tag without --replace (validates the v2.9.8 safety going the right direction)
    • Marcelle's live v2.9.8 install continued to run through the test (no teardown needed)
    Downloads
  • admin released this 2026-04-16 13:21:44 -06:00 | 10 commits to main since this release

    Installation UX & CCP Integration Polish

    This release is the outcome of an end-to-end install-testing sprint on a clean host. Ten friction points surfaced — all addressed. No image rebuilds in this release (changes are scripts + docs); the v2.9.7 container images are still current.

    Upgrade notes: Safe upgrade for existing installs — no schema changes, no breaking flag changes. ./scripts/upgrade.sh picks up the new tarball; admin users can re-run bash config.sh to regenerate the Next Steps block if desired (not required).


    Install flow hardening

    Host-port preflight in install.sh (commit a7daf5ff)

    The installer now runs ss -Htln against the ~14 required ports before downloading the tarball and aborts with specific remediation hints if any are bound. Catches the cockpit-on-9090 class of collision that previously manifested as a partial-stack startup failure mid-compose up.

    [OK]    Prerequisites OK
    [OK]    Docker daemon is running
    [OK]    Disk space: 143677MB available
    [OK]    Host ports available
    [INFO]  Downloading Changemaker Lite v2.9.8...
    

    Admin password persistence (commit b92ca4f3)

    When config.sh -y is run without --admin-password, the auto-generated password is now written to data/admin-credentials.txt (mode 0600) in addition to being printed once to stdout. Users piping output to tee or missing the scroll no longer lose the password. Explicit --admin-password is never persisted.

    Pangolin credential smoke test (commit b92ca4f3)

    config.sh -y now verifies --pangolin-api-key/--pangolin-org-id against /org/:id/resources before committing them to .env. Typos and revoked keys fail fast with a clear message instead of surfacing much later as a broken Newt tunnel. Skip with --skip-pangolin-check for offline bootstrap.

    Next Steps surface new tools (commit a7daf5ff)

    After config.sh -y completes, the Next Steps block now points users at:

    • bash scripts/test-deployment.sh --wait 60 — verify the install is healthy
    • bash scripts/validate-env.sh — re-check .env + host ports
    • bash scripts/pangolin-teardown.sh — clean reset before reinstall

    Also notes the realistic first-boot timing (~3 min image pulls + ~90s stabilization) so brief unhealthy statuses don't confuse first-time users.


    New scripts

    scripts/pangolin-teardown.sh (commit 6602d14e, shipped in release)

    Wrapper for wiping a Pangolin org's resources + sites before a fresh install. Reads credentials from .env or takes --api-url/--api-key/--org-id flags. Dry-run by default; --yes to execute. Deletes resources before sites to avoid orphans. Safety via --keep-site-ids.

    scripts/ccp-deregister.sh (commit e8c862f7, shipped in release)

    Companion to pangolin-teardown.sh for installs that phone-home registered with a Changemaker Control Panel. Removes the CCP-side Instance row during teardown. Without this, a stale row blocks re-registration of the same slug. Dry-run by default. Matches by agentUrl (default from .env), --slug, or --instance-id.

    Full teardown sequence for a CCP-registered install:

    bash scripts/ccp-deregister.sh --token $ADMIN_TOKEN --yes
    bash scripts/pangolin-teardown.sh --yes
    docker compose --profile monitoring down -v --remove-orphans
    sudo rm -rf ~/changemaker.lite
    

    Changemaker Control Panel integration

    Tunnel cleanup on deleteInstance (commit 6602d14e)

    CCP admins clicking "Delete Instance" previously left the Pangolin site + all its resources orphaned for the lifetime of the org. Now deleteInstance() calls teardownTunnel() before composeDown when pangolinSiteId is set. Best-effort with try/catch matching the existing Docker-cleanup tolerance pattern — if Pangolin API is unreachable, the delete still completes.

    Slug conflict returns clean 409 (commit b8ec6286)

    The agents/registrations/:id/approve handler previously leaked a raw PrismaClientKnownRequestError on slug uniqueness violations. Now returns a 409 SLUG_CONFLICT with a message pointing at the fix:

    "Slug 'changemakerlite' is already in use by another Instance. Delete
    the stale instance first (DELETE /api/instances/:id) or run
    scripts/ccp-deregister.sh from the target host."
    

    Agent poll rate limit + exponential backoff (commit c8d0e9fe)

    Split the one-size-fits-all rate limiter:

    • /register keeps the strict 10/15min (invite-code brute force is the real attack surface)
    • /poll gets a new looser limiter at 180/15min (one poll per ~5s upper bound)

    Agent-side: replaced the fixed 30s setInterval with a self-scheduling setTimeout loop that backs off exponentially on HTTP 429 (30s → 60s → 120s → 300s cap) and resets to 30s on any successful poll. Fixes the "agent wedged at 429, restart required" workaround that bit us at the 15-minute approval SLA mark.


    Release hygiene

    build-release.sh --replace safety (commit 8fdcded2)

    --upload now checks for an existing release at the given tag before POSTing. If found and --replace is not set, errors out with a clear warning. Prevents the silent-overwrite problem where users on a version see "no update available" because the upgrade-check compares tags, but the tarball contents have changed underneath them. --replace remains available for deliberate test-bench iteration (DELETE + recreate).

    Shipped scripts added to tarball whitelist

    scripts/build-release.sh now includes validate-env.sh, pangolin-teardown.sh, and ccp-deregister.sh in the release tarball. Previously these existed in source but weren't packaged.


    Documentation

    Docs are the point of truth; all the above is reflected in:

    • mkdocs/docs/docs/getting-started/prerequisites.md — new warning covering cockpit and host-port collisions
    • mkdocs/docs/docs/getting-started/installation.mdtest-deployment.sh workflow, admin password file, teardown sequence
    • mkdocs/docs/docs/getting-started/first-steps.md — where to find the generated password
    • mkdocs/docs/docs/getting-started/control-panel.md — new "Registering an Existing Install (Phone-Home)" section with rate-limit + backoff behaviour and the ccp-deregister.sh teardown path
    • README.md — Quick Start block reflects reality including useful-tools list
    • DEV_WORKFLOW.md--replace safety for release hygiene

    Verified end-to-end

    The release was validated on a clean Ubuntu Server test bench (hostname marcelle): teardown → fresh install via install.shconfig.sh -y --enable-all with --ccp-* flags → docker compose up -dtest-deployment.sh --wait 60:

    • 37/37 passed, 0 warnings, 0 skipped (all containers healthy, API responding, tunnel subdomains reachable, DB seeded)
    • CCP registration round-trip works first-try (certs delivered on 2nd poll, ~60s)
    • SLUG_CONFLICT 409 surfaces correctly when re-registering without deregister
    • ccp-deregister.sh --yes unblocks re-registration cleanly
    • build-release.sh --upload refuses to overwrite existing tag without --replace
    Downloads
  • admin released this 2026-04-15 18:33:13 -06:00 | 18 commits to main since this release

    Bug fix — VERSION promotion regression

    Single-commit patch release fixing a regression in the health-check logic that incorrectly gated VERSION promotion on soft warnings, causing upgrades to roll back unnecessarily.

    Commits:

    • Fix VERSION promotion regression: don't gate on soft health-check warnings (0cd7ba3a)

    Upgrade notes: Safe upgrade; recommended if you've seen unexpected rollbacks after an upgrade.

    Downloads
  • admin released this 2026-04-15 16:57:13 -06:00 | 19 commits to main since this release

    Update system hardening bundle 3 — breaking-release gate, release-mode rollback, Phase 7 budgets, symmetric success archival.

    Downloads
  • admin released this 2026-04-15 16:13:04 -06:00 | 20 commits to main since this release

    Upgrade infrastructure hardening

    Makes upgrade failures observable and adds an out-of-band smoke test from the host.

    Commits:

    • Upgrade failure visibility + atomic VERSION + external smoke test (7c25a2d5)

    Key changes:

    • VERSION file is now written atomically — upgrades either complete fully or not at all, no half-promoted state
    • Upgrade failures surface in admin UI instead of silently reverting
    • scripts/test-deployment.sh can be invoked externally (from dev machine or CI) against the running stack

    Upgrade notes: Safe upgrade.

    Downloads
  • admin released this 2026-04-15 15:40:59 -06:00 | 21 commits to main since this release

    Upgrade watcher timeout extended

    Single-commit patch: raises the systemd changemaker-upgrade.service TimeoutStartSec from 900s to 3600s. Heavy upgrades (image pulls + migrations + seed) can legitimately exceed 15 minutes on slower networks.

    Commits:

    • Bump upgrade watcher TimeoutStartSec 900s → 3600s (39a1b717)

    Upgrade notes: If you have the upgrade watcher installed, re-run bash config.sh (Step 13) or manually update /etc/systemd/system/changemaker-upgrade.service to pick up the new value.

    Downloads
  • admin released this 2026-04-15 11:57:50 -06:00 | 22 commits to main since this release

    Fresh-install + upgrade-path hardening

    Addresses friction surfaced during fresh-install testing — specifically, a boot race between nginx/newt and the API healthcheck window.

    Commits:

    • Fix nginx/newt boot race by raising API healthcheck start_period to 120s (b8a14d1f)
    • Fresh-install + upgrade-path hardening bundle (f07e1961)

    Key changes:

    • API healthcheck start_period bumped 60s → 120s so nginx/newt don't panic during initial migrations
    • Miscellaneous fresh-install and upgrade edge cases from test-bench iterations

    Upgrade notes: Safe upgrade.

    Downloads