Skip to content

Epo v3.0.0

Choose a tag to compare

@github-actions github-actions released this 27 Aug 18:45
Immutable release. Only release title and notes can be modified.

Epo v3.0.0

macOS (Apple silicon · Intel) Windows 10 / 11 open source (MIT) local-first

Highlights

This release rolls up the changes listed below.

Changes

Every commit since 0d3f680
  • fix(release): root-anchor the release/ ignore so the release cards commit (1c29bb3)
  • feat(release): auto-releaser, release cards, and the in-app self-updater (f884b76)
  • ci: SHA-pin every action; close the zizmor findings; fix Windows packaging (1478f99)
  • ci: security, health, hygiene, and rehearsal workflows; coverage in the gate (6e94f7c)
  • style(lint): organize imports repo-wide; the lint gate becomes biome ci (30eff88)
  • ci(dependabot): adopt the FableFactions auto-merge pattern (bdb857f)
  • docs(readme): brand README, full asset system, and nightly live panels (178d439)
  • feat(console): stage-hosted graph and prune pages, intro tour, durable window state (92a01ab)
  • feat(shell): claim the Epo app identity in dev runs; regenerate the icon set (716bb97)
  • chore(deps): bump the npm-minor-patch group with 3 updates (#11) (3e4eb70)
  • style(brand): crop the README hero wordmark to its content bounds (4425c14)
  • feat(prune): bio filter — protected words in a profile bio block the unfollow (af32167)
  • feat(timing): per-cycle volume plan fluctuates just under the daily caps (0283ab2)
  • chore(deps): bump @swc/core in the npm-minor-patch group (#10) (db1ed7f)
  • fix(prune): cap counts per active-hours cycle; scans stay fresh 4 days (447fa11)
  • fix(governors): actions counter resets at the active-hours cycle start, not midnight (5af8cc2)
  • fix(ui): focus management, layering, motion single-sourcing, live badges (1c74b12)
  • fix(main): teardown lock closes the rebuild races; identity re-validation (783c013)
  • fix(rim): feed shape drift is a typed failure, not an empty success (bd6c9f8)
  • fix(engine): step-level generation token, woven-feed accounting, policy constants (d02033f)
  • fix(timing): one home per constant — units module, live registry, mixture fallback (e6c0d73)
  • fix(brand): true dev Dock identity — transparent icon, 15% smaller mark, Epo name (dd2e8e1)
  • feat(brand): dark liquid-glass app icon (f9bc524)
  • feat(ui): settings-page revamp (collapsible cards, Behavior/Advanced); tooltip + card-entrance animation fixes (553a5ad)
  • feat(settings): qualitative pattern model (personas + knobs) deriving the pacing config; follow-plan daily volume (af43497)
  • feat(main): wire SessionPlanner + woven prune feed into the composition root; scan-and-enqueue scheduled prune (470ff85)
  • feat(collection): timing/interaction integration across store, rim, and adapter layers (8bda8f3)
  • feat(engine): session-driven organic pacing loop with woven prune feed; rolling-hour velocity signal (3ba0d53)
  • feat(timing): timing package + organic macro-timing model — distributions, circadian field, session planner, statistical harness (4e91075)
  • refactor: rename humanizer → interaction (neutral naming); retire request-budget/metering (c3fd12a)
  • docs: refresh plans/specs, add CLAUDE.md and the macro-timing-realism plan (0375465)
  • fix(prune): zero the stale candidate count when a fresh scan begins (7c31539)
  • feat(humanizer): real trusted input events with human motion profiles (839b1fa)
  • refactor(harness): dev harnesses use timing primitives + registry; timing unification complete (edca55f)
  • feat(renderer): real countdown deadlines, shared keep-alive hook, timer-leak and settings-desync fixes (a2e292e)
  • feat(adapter): cancellable waits — driver run token interrupts DOM polls and pacing (6bf4714)
  • refactor(main): probe + auto-prune watcher ride ScheduleManager; shared DelayManager wired (84a514c)
  • feat(engine): persist the follow-back sweep cadence across restarts (75f6ebb)
  • feat(ui): reset content scroll to top when switching views (a1af113)
  • refactor(prune): waits through DelayManager, delay formula composed from shared policies (5a86fec)
  • feat(ui): NumberTicker — slot-machine odometer digits for live counters (22b975a)
  • refactor(engine): waits through DelayManager — named keys, real nextActionAt deadline (fafdef8)
  • feat(prune): live mid-scrape counts — onProgress from page reader to throttled status emits (daff73f)
  • refactor(timing): rate-governor + page-reader delegate to shared delay policies (c6e1060)
  • feat(timing): ScheduleManager — overlap-guarded tick loops and persisted cadences (d519712)
  • docs: design for live scrape counts, number tickers, scroll reset, humanizer (2f94500)
  • feat(timing): DelayManager — named, cancellable, observable waits (04c16c0)
  • feat(timing): namespaced registry for all fixed operational timing constants (4e5f25f)
  • feat(timing): pure delay primitives — sleep, DelayPolicy, withTimeout (1f4172d)
  • docs: timing unification implementation plan (2d884fb)
  • docs: timing unification design — DelayManager, ScheduleManager, timing package (1217f88)
  • feat(prune): run unfollows at 1/3 of the humanized delay (34227ce)
  • ci: gate public-only security workflows on repo visibility (6ab27e3)
  • ci: pin scorecard-action to v2.4.4 + add Dependabot auto-merge (d27cef9)
  • build: adopt TypeScript 7 native toolchain — swc/jest + Biome (71c7ea9)
  • ci: run on Node 25 and bump all GitHub Actions to latest majors (ec446e8)
  • docs: v3 design spec, phase plans, UI mockup (55bba8d)
  • ci: GitHub Actions (CI, CodeQL, Scorecard, dependency-review, release), Dependabot, security policy, templates (b7f2d9e)
  • brand: Epo identity — metallic 'e' monogram, hero art, app icons, ground-up README (76b58ad)
  • harness: capture/inspect/livetest updates for the versioned adapter surface (5966b63)
  • renderer: Command Console redesign — Overview/Growth/Queue/Prune/Settings, Prune view (2-step scan→run, whitelist, schedule) (ee940a9)
  • main: composition root — IPC, prune tab hand-off (pause/resume growth), automation veil over scan+prune (09b9a95)
  • settings: single knob set + projections — prune config (whitelist, daily cap, scan pacing); shared IPC types (6bc503d)
  • engine: Phase 5 auto-prune — PruneEngine, 2-step scan→run, growth-managed exclusion, shared-graph census (e0d5ce9)
  • engine: paced growth loop — churn lifecycle, offline hold, pause-park handshake for the prune hand-off (6da1c48)
  • rim: paced ports — followers-page reader, relationship reconciler, own-following/followers scan sources (469eefa)
  • adapter: version-marked IG surface — reader/actor/sentinel, robust identity, FetchEnvelope, live-tab guard (30b68d1)
  • store: event-sourced knowledge graph — async reconciliation (leave-alone), prune ledger, scan-census enrichment (4ecd773)
  • build: modernize toolchain — TS6, ESLint 10 flat config, esbuild 0.28, electron-builder, epo CLI harness (3137bed)
  • docs: live gate PASSED — full pipeline validated live; first-run guidance (93cea88)
  • test(rim): fake actor scrollFollowers returns boolean (matches new best-effort signature) (8a06f80)
  • fix(adapter): scrollFollowers is best-effort — no container is not fatal (a350961)
  • fix(adapter): open followers modal by clicking the text-matched stat link, not a dead href (f083887)
  • Add DOM element inspection harness (npm run inspect) (b872e1c)
  • fix(adapter): open followers modal by navigating to /followers/ (Task-E-proven), not clicking a drift-prone link (e392020)
  • fix(identity): resolve own username via profile link/nav, not the failing current_user endpoint (1b3bab8)
  • docs: add live action smoke-test (npm run livetest) as the quick pre-gate check (b7bc1eb)
  • Wire livetest entry into esbuild + npm scripts (959e896)
  • Add live action smoke-test harness (src/livetest) (5cebfde)
  • docs: handoff — remediation complete, live gate ready (216 tests green) (6d555d6)
  • Complete v3 composition-root wiring (R1/R3/R5, f6/f11/f14/f15) (611e9fe)
  • f13: support overnight (wrapping) active-hours windows (17b4fc5)
  • engine: candidate enrichment + bounded refill cycle, generation-token loop, budget pre-check, per-step resilience (R1, R2, R4, f9, f10) (8a95de8)
  • scanner: mark scored-and-rejected candidates role='skipped' so the pool shrinks (R1.3) (50a0abe)
  • store: exclude role='skipped' from candidate pool; require explicit clock time for scrape cursors (R1.4, f8) (7efad34)
  • f11: own-followers sweep stores its parsed observations (d4423ec)
  • R4+f12: discriminated churn outcome; blocked-untouched and dry-run edge/ledger safety (1ec9185)
  • R1.1: add ProfileEnricher rim port for candidate count enrichment (d273f32)
  • docs: handoff — flag critical integration review + remediation-in-progress (hold live gate) (3a2f46a)
  • docs(remediation): Fable triage of assembled-system review — R1 enrichment + R2-R5 safety fixes (6dd3dca)
  • renderer: v3 instrument-panel dashboard (spec §1-§6) (658616c)
  • ipc: add read-only chain/queue/settings handlers (spec §5) (cf393de)
  • engine: support live config reload on settings change (71485d7)
  • docs: overnight build handoff — status, architecture, live-gate checklist (1ea4a7e)
  • Wire Wave 4: minimal engine Start/Pause/Stop controls + live status line (6e6e489)
  • Wire Wave 4: route engine controls + pushed status through IPC/preload (c26bc8e)
  • Wire Wave 4: Foundation composition root + lazy Engine graph (56046e4)
  • Wire Wave 4: extend IPC/status contract, drop dead adapter.reader slot (E2) (d2ff2df)
  • docs(ui): Fable-authored metallic-minimal dashboard design (panels, data bindings, IPC) (64792ef)
  • Test the Engine runtime with fakes: pacing, gates, cadence, chain, E1 (1dd1d28)
  • Add Engine runtime: the paced, interruptible conductor (v3 §3) (10fab85)
  • rim: adapter-backed port implementations (acquisition, churn actions, own-followers) (9357ae1)
  • rim: RimTab seam, request metering (R2), shared followers scraper (R1/R3/R5) (d03c1a7)
  • store: add scrape_cursors table + cursor persistence (R4) (c4734e2)
  • test(adapter): cover A1 retry, A2 fallback anchor, A3 verification, A4 pk extract (4ecc91f)
  • adapter(A1/A2/A3): hydration-wait initial lookup, fallback search, verify post-click (082d52a)
  • adapter(A4): Reader.extractTargetPkFromFollowersUrl (750977c)
  • adapter(A2/A4): defensive fallback button anchor + case-tolerant followers link (6e5b9a5)
  • Add Settings object + config projections (v3 Task 2) (3fa7f19)
  • Split ChurnScheduler.tick into advanceTimers/nextDue/execute (92854db)
  • docs(arch): fold adversarial-review findings into engine architecture as owned requirements (1f14265)
  • docs(arch): Fable-authored Engine runtime architecture (conductor + pacing relocation) (96b551a)
  • Add Chain Controller: next-target promotion + own-followers fallback (b6ddc92)
  • Add Target type + store methods for chain targets and yield stats (9b06a3c)
  • Test Scanner planning against a real in-memory KnowledgeStore (3b7d265)
  • Add Scanner: rank a target's followers and enqueue follow candidates (3d21e57)
  • test(engine): cover Churn Scheduler transitions and rate-gate safety (e7862aa)
  • feat(engine): add Churn Scheduler lifecycle state machine (§3.4) (9c8eddb)
  • test(engine): Follow-back Watcher with fake follower source (b51ac9c)
  • feat(engine): request-minimal Follow-back Watcher (§5.1) (1bc6587)
  • feat(main): wire Phase 1 foundation behind IPC (tab+adapter+store+governors) (6e6bd63)
  • test(store): cover follow_records API, candidate pool, and role round-trip (c2c8adb)
  • store: add churn/candidate query+mutation API to KnowledgeStore (ab80a44)
  • store: add FollowRecord/FollowState types and AccountState.role (89373bc)
  • Test the Scorer: ratio curve anchors + candidate eligibility (d03c10c)
  • Add ratio sweet-spot Scorer (P2-A) (aeead30)
  • test(adapter): health-checks throw AdapterStaleError; Sentinel label mapping (014370a)
  • feat(adapter): Actor + Sentinel + facade over live-verified field notes (82cb6d3)
  • feat(adapter): AdapterStaleError for loud selector-drift failures (da11580)
  • feat(adapter): Reader parsing live-verified IG responses into observations (7698de9)
  • test(adapter): sanitized IG response fixtures for Reader (8eef754)
  • feat(adapter): field-notes.ts — live-verified IG endpoints, JSON paths, selectors, signatures (50cad61)
  • feat(capture): always drive profile-shape capture, never dead-end (06ec6af)
  • feat(capture): deterministic captureProfileShapes for the 3 missed shapes (3457d74)
  • feat(capture): classify friendships/show// as friendship-show (e4004eb)
  • fix(deps): bump better-sqlite3 11->13 for Electron 43 V8 compatibility (040d710)
  • fix(macos): upgrade Electron 31->43 and auto-sign dev binary (4ab8247)
  • chore(capture): wire capture build/script, gitignore payloads, add docs (4511cfb)
  • feat(capture): Task E capture harness and Electron entry (07195cf)
  • test(capture): url classifier for Task E capture harness (bddc133)
  • chore: ignore bare node_modules symlink (prevents worktree footgun) (fafd07a)
  • chore: stop tracking node_modules symlink (worktree artifact) (5000399)
  • feat(governors): durable rate cap, hard ceiling, request budget, injectable clock (fb5efca)
  • feat(store): KnowledgeStore with migrations, observe(), edges, ledger, queries (c2dff64)
  • feat(renderer): minimal Preact control shell with metallic-minimal styling (35ae04e)
  • feat(main): electron shell, side-by-side IG tab, IPC stubs, preload on/off bridge (6af3b69)
  • feat(adapter): InstagramTab on persistent session with CDP response observer (7b0bcb3)
  • feat(store): per-field provenance-aware projection with confidence merge (9c5208e)
  • feat(store): knowledge-graph types, sources, confidence, ratio (0cda4bb)
  • docs: add @typescript-eslint/parser to Task 1 deps (needed by eslint parser) (e214d1e)
  • chore: reset to clean v3 foundation with sqlite build, jest, eslint store-boundary (5e2b8a9)
  • docs: fix Task 1 for v3 clean-start (create fresh tsconfig/esbuild, no v2 tooling) (1703176)
  • chore: ignore .DS_Store and .serena tooling on v3 (721d7e5)
  • docs: add Peanut v3 implementation plan (verified-foundation-first) (c69340a)
  • docs: add local knowledge-graph pillar to Peanut v3 spec (16fccc9)
  • docs: add Peanut v3 ground-up redesign spec (4536d7f)
  • Redesign Peanut Control Center interface (9ed5901)
  • Improve Instagram scraping stealth and scrolling (fa04934)
  • Add Electron control center and improve scraping (5aed478)
  • Switch to manual login flow (2c1e9bc)
  • Create Instagram automation CLI (72571ad)

Install

macOS — download Epo-3.0.0-arm64.dmg (Apple silicon; Intel builds ship from v3.0.1), open it, and drag Epo to
Applications. These builds have a known packaging flaw: macOS reports the app "damaged". Rescue once from a terminal: xattr -cr /Applications/Epo.app — or skip to the newest release, which opens normally via System Settings → Privacy & Security → Open Anyway.

Windows — download Epo-Setup-3.0.0.exe (recommended — it
updates itself from here on) or Epo-3.0.0-portable.exe.
SmartScreen may warn on first run: More infoRun anyway.

Already running Epo? Windows installs update themselves in the
background; macOS shows the new version in Settings → Updates and brings
you here.

Notes

  • Your database, settings, and Instagram session carry over — updating is a
    drop-in replacement.
  • The .zip, .blockmap, and latest*.yml assets below are the
    self-updater's feed; every file stays attached.
  • Epo acts on your Instagram account; use it at your own risk (see the
    README).

Full changelog: 0d3f680...v3.0.0