Per SPEC v0.7 §"oh CLI" deprecation. Atomic file-deletion mass: - Removed packages/sandbox/ workspace (CLI + harness/onboard/lib/tools + tests) - Removed packages/sandbox entry from pnpm-workspace.yaml - Removed link:cli script from root package.json - Removed .github/workflows/build.yml (was duplicating release.yml's image build, pushing to ghcr.io/ryaneggz/open-harness — drifted from canonical ghcr.io/ryaneggz/openharness produced by release.yml) - Removed .github/workflows/ci.yml (sandbox-only CI now stale) - Removed CLI build/symlink block from .devcontainer/entrypoint.sh that wired /usr/local/bin/openharness and /usr/local/bin/oh - Rewrote .husky/pre-commit to run root-level lint + test (was cd'ing into the now-deleted packages/sandbox/) - Regenerated pnpm-lock.yaml (-49 packages) release.yml is now the sole image producer pushing ghcr.io/ryaneggz/openharness:<tag> + :latest. Refs #210
13 KiB
13 KiB
Changelog
All notable changes to this project are documented here.
Format follows Keep a Changelog; versions use CalVer (YYYY.M.D with -N suffix for same-day releases) and match git tags.
Update policy and release automation live in .claude/rules/git.md § Changelog.
[Unreleased]
Removed
- BREAKING:
@openharness/sandboxCLI removed;docker composeis the canonical substrate. Deleted thepackages/sandbox/workspace package (CLI binary + harness/onboard/lib/tools source + tests), the entry frompnpm-workspace.yaml, thelink:cliscript from rootpackage.json, the now-stale.github/workflows/ci.yml(sandbox-only CI), and the duplicate.github/workflows/build.yml(which had been pushing a driftedghcr.io/ryaneggz/open-harnessimage alongside the canonicalghcr.io/ryaneggz/openharnessproduced byrelease.yml). The CLI build/symlink block in.devcontainer/entrypoint.shthat wired/usr/local/bin/openharnessand/usr/local/bin/ohis gone.release.ymlis now the sole image producer. Per SPEC v0.7 §"oh CLI". (#210) - BREAKING: heartbeat daemon removed. Deleted
packages/sandbox/src/lib/heartbeat/(~1,752 LOC),packages/sandbox/src/cli/heartbeat-daemon.ts,packages/sandbox/src/cli/actions/heartbeat.ts,packages/sandbox/src/tools/heartbeat.ts, theoh heartbeat {start,stop,status}command group, theheartbeat-daemonpackage bin, the sevenheartbeat-*.test.tssuites, and.claude/skills/heartbeat/. Heartbeat env vars (HEARTBEAT_ACTIVE_START/_END/_AGENT) stripped from.devcontainer/docker-compose.yml; the legacy daemon-startup blocks ininstall/entrypoint.shand the/usr/local/bin/heartbeat-daemonsymlink in.devcontainer/entrypoint.share gone;install/banner.shno longer advertisesheartbeat-daemon status. The croner runtime (scripts/cron-runtime.ts, US-002/US-003/US-004) is the canonical replacement per SPEC v0.7 §"Croner runtime". (#210) - BREAKING:
@mariozechner/pi-coding-agentis no longer a dependency. The pi agent CLI and Mom Slack bot have been extracted to a separate harness pack atryaneggz/mifune(npm:@ryaneggz/mifune). Install withoh harness add @ryaneggz/mifune. (#208)
Added
- Seeded the two SPEC-reserved crons:
crons/heartbeat.md(hourly pulse,0 * * * *) andcrons/cleanup-tasks.md(Sunday 23:00,0 23 * * 0). Bodies follow SPEC v0.7 §"Croner runtime" + §"Weekly cleanup cron"; substrate stays empty otherwise so users add their own. (#210) .devcontainer/entrypoint.shnow startsscripts/cron-runtime.tsin asystem-crontmux session on container boot, replacing the legacyheartbeat-daemonwatchdog block. Idempotent (tmux has-sessionguard); restart policy is per-container-start per SPEC v0.7 §"Croner runtime". (#210)scripts/cron-runtime.ts— minimal croner-backed runtime (≤120 LOC) that readscrons/*.mdfrontmatter, schedules per-cron tasks, runs the body as a prompt toclaude -p(or$CRON_AGENT_BIN), logs tocrons/cron-runtime.log, and uses a PID-lock atcrons/.pidto prevent double-firing. Replaces the 1,900-LOC heartbeat daemon per SPEC v0.7. (#210)- SPEC v0.7 amendments at
.claude/specs/structure-spec-v0.7.md— additive-only revision resolving seven v0.6 conflicts (canonical image name, docs path,ohCLI deprecation, croner runtime contract, hook execution mechanism, memory directory format, tasks vs.ralphpaths) and adding sections for harness packs, orchestrator-vs-workspace skill scope, and shrunk prose on Docusaurus config / eval flakiness / wiki-sync rubric / blog authorship / weekly cleanup. (#210) - README "Docker only (no installer)" section — concise compose-based deploy path for hosts that have only Docker + git.
- Per-page OpenGraph + canonical link tags via theme.config.tsx head function (#140).
- Blog post draft: Worktree-per-agent — stages for Wed publish (#145).
- Blog section at /blog and About page nav entry (#143).
- Blog post: BYOH — stop installing agent CLIs on your laptop (#144).
- Root
CHANGELOG.mdand Keep-a-Changelog workflow documented in.claude/rules/git.md;/releasenow promotes[Unreleased]to the new version section at tag time. - Generate
sitemap.xmlandrobots.txtduring docs build vianext-sitemap(#141). - Launch runbook consolidating manual cutover steps (DNS, GH settings, OG validation, GSC, promotion).
- Docusaurus v3 docs site at
apps/docsdeployed to oh.mifune.dev (#164).
Changed
install.shcurl-pipe target renamed~/.openharness→~/openharnessso the cloned project no longer collides with the in-repo.openharness/config dir (~/.openharness/.openharness/was visually and semantically confusing). One-time migration: existing~/.openharnessclones aremv'd to~/openharnessautomatically when the new path is absent. In-container paths (/home/sandbox/.openharness) are unchanged. (#200)- Reverted the sandbox/orchestrator vocabulary realignment (#170, #172). The in-container Linux user is
sandboxagain (UID/GID 1000 preserved); theORCHESTRATOR_USER/ORCHESTRATOR_HOMEconstants are removed. The package name@openharness/sandbox, compose service, container default,SANDBOX_NAMEenv var,POSTGRES_USER, andsandbox_*Pi tool prefix were never changed.install/banner.shcarries an inverted migration guard for users coming back from a renamed image. (#198) - Consolidate documentation:
/docs/is now the single source of truth, served by Docusaurus fromapps/docs/viapath: '../../docs'. Enabled blog at/blog/. Removed the duplicateapps/docs/docs/tree. (#178) - Installer auto-detects Node 20+; new
--cli/--docker-only/--install-nodeflags;--with-clideprecated. (#176). - README and installation docs now use the short
https://oh.mifune.dev/install.shURL (302 redirect to the raw GitHub install script onmain) instead of the longraw.githubusercontent.comURL. /releasenow executes the[Unreleased]→[$VERSION]promotion (was prose-only) andrelease.ymlsources the GitHub Release body from the promoted CHANGELOG section viabody_pathinstead ofgenerate_release_notes, so the GitHub Release notes match the changelog byte-for-byte.- Revert prior secondary product name; "Open Harness" is the sole brand across README, docs, and onboarding (#157).
- Cloudflare onboarding step now requires an explicit public hostname (no default domain) (#157).
- Slim README to ~110 lines, lead with oh CLI flow (#139).
- Wiki promoted from
workspace/wiki/todocs/wiki/— same structure (pages/,sources/,index.md,log.md), now top-level alongside human-curated docs. - 26 docs pages converted from Nextra MDX to plain markdown rendered by GitHub.
Fixed
install.shnow auto-disables the*-host.ymloverlays in.openharness/config.jsonwhen host UID ≠ 1000 (was: a multi-line warning telling the user to do it by hand). Mode-0600 credential files in~/.claude/~/.codex/~/.pican't be read across UIDs, and mode-0700 dirs (e.g.~/.pi/agent/sessions/) reject writes from non-owner UIDs — the sandbox user (UID 1000) would EACCES onoh/claude/codex/pi. The new logic usesjqto filterclaude-host.yml,codex-host.yml,pi-host.ymlout ofcomposeOverridesso the base named volumes take over. The original warning is retained as ajq-missing fallback. (#202)- Host auth (
~/.claude,~/.codex,~/.pi) is shared into the sandbox again.install.shnow pre-creates the three auth dirs and~/.claude.json(empty if missing) before sandbox bring-up so docker can't auto-create them root-owned, andclaude-host.yml/codex-host.yml/pi-host.ymlare restored to defaultcomposeOverrides. UID-mismatch hosts (UID ≠ 1000) get a loud install-time warning telling them to drop the overlays from.openharness/config.json(mode-0600 credential files can't be read across UIDs). Together this restores the convenience that was lost in #194 / #195 without re-introducing the EACCES failure mode that motivated those PRs. (#196) oh/claude/codexno longer fail withEACCES(or silent re-auth) on freshinstall.shinstalls. Removeddocker-compose.claude-host.yml,docker-compose.codex-host.yml, anddocker-compose.pi-host.ymlfrom the defaultcomposeOverridesin.openharness/config.json. Each overlay's own header documents that it requires host UID 1000 + the source dir to pre-exist; shipping them as defaults broke any host where either condition wasn't met (docker auto-creates missing source dirs as root → sandbox user (UID 1000) can't write). The base compose'sclaude-auth/codex-auth/pi-authnamed volumes now take effect by default;entrypoint.shchowns them to UID 1000 on first boot. Single-laptop developers wanting cross-sandbox auth sharing can opt back in by appending the relevant overlay(s) to.openharness/config.json. (#194)oh sandboxno longer fails on freshinstall.shinstalls with a Caddyfile bind-mount error. Removeddocker-compose.gateway.ymlanddocker-compose.cloudflared.ymlfrom the defaultcomposeOverridesin.openharness/config.json; both are additive overlays now loaded only when needed (oh exposere-adds the gateway viaSandboxConfig.addOverride()). (#192)install.shnext-steps now leads with a numbered "source your shell rc" step that detects$SHELL(bash→~/.bashrc,zsh→~/.zshrc,fish→~/.config/fish/config.fish) so users don't have to exit + reopen their shell to pick upoh/node/pnpm. Curl-piped install runs in a child bash whose exports cannot reach the parent shell — the source step is now Step 1 of next-steps (was a buried "Reminder").install.shbootstrapsPNPM_HOMEbeforepnpm link --globalso the CLI install no longer dies withERR_PNPM_NO_GLOBAL_BIN_DIRon fresh nvm-installed Node. Runspnpm setup(writesPNPM_HOMEexport to~/.bashrc+~/.zshrc) and also exportsPNPM_HOME/PATHinline so the link step succeeds in the current shell regardless of rc state.install.shno longer silently exits when sourcing a pre-existing~/.nvm/nvm.shunderset -euo pipefail. nvm + corepack calls are bracketed with relaxed strict mode and explicit$?checks, anERRtrap surfaces unexpected failures with the failing command and line, and pnpm is pinned to10.33.0(matchespackage.json#packageManager) instead of resolvingpnpm@latestover the network on every install.- Slack bot no longer drops oversized agent replies with cascading
msg_too_longerrors. Main message is capped at 2,900 chars with a_message truncated — full response in thread_footer; full content spills to thread replies;setWorking(false)always clears the working indicator. (#135)
Removed
- Removed legacy
/docs/{plans,wiki,launch-runbook,blog}/andapps/docs/docs/tree (consolidated into/docs/). (#178) - Nextra docs site and the
.github/workflows/docs.ymldeployment — documentation is now plain markdown indocs/, read in the GitHub UI. - Reference Next.js application at
workspace/projects/next-app/, along with its CI jobs (workspace/projects/next-apppaths inci.yml/release.yml) and the release pre-flight gate referencing it. - Root
package.jsonscripts:dev,docs:dev,docs:build,docs:preview.
Deprecated
Security
Release history prior to this file: see git tags and GitHub Releases. Most recent pre-changelog tag: 2026.4.22.