All notable changes to this project are documented here.
Format follows Keep a Changelog; versions use SemVer (MAJOR.MINOR.PATCH), read from root package.json, and ship as v-prefixed git tags.
Update policy and release automation live in /git Β§ Changelog.
- Add
oh sandbox install docker: a wizard writes a sandbox registry entry under${OH_HOME:-~/.oh}/sandboxes/<name>/and boots it from any directory, with no project checkout. (#950) - Add
oh sandbox list [--json], reporting each registry entry's name, runtime, container status, and bound repo. (#950) - Add
--sandbox <name>tooh config show|setandoh secret set|list, which read and write a registry entry instead of the project root. (#950) - Add
microsandboxto the tool catalog:oh tool install microsandboxinstallsmsbunder${NPM_USER_PREFIX:-$HOME/.local}from a pinned installer. (#950)
- BREAKING:
oh updateis the bootstrap: it equips an empty checkout with.oh/andcrons/, writes nothing else, and never prompts. (#950) - BREAKING:
oh shell|stop|restart|logs|ps|destroytake an optional sandbox name, resolving name, then the single entry, then the entry containing the cwd. (#950) oh destroy <name>removes the registry entry afterdown -v, so the sandbox name becomes free again. (#950)docs/deployment-prebuilt-image.mdbecomes theoh sandbox install dockerpage: running the published image is now the default, and--repois the bind-mounted-checkout case. (#950)
- Remove boot provisioning and every install switch:
oh harness install <id>andoh tool install <id>are the only door. A fresh sandbox has no harness and noherdr. (#948) - BREAKING: Remove
oh init.oh sandbox install dockerowns sandbox configuration andoh updateowns the control-plane payload. (#950) - BREAKING: Remove
oh runtime. The runtime catalog lives underoh sandbox, andmsbis installed withoh tool install microsandbox. (#950) - BREAKING: Remove the
.oh/templates/scaffold payload. The CLI writes noAGENTS.md, provider config, or.gitignoreline beyond.env. (#950) - Remove
gvisorfrom the runtime catalog; the isolation-tier landscape lives indocs/rfcs/rfc-runtime-support.md. (#950)
- Add
spec-no-agent-handoff,spec-no-advisor-session-coupling,cleanup-no-agent-session-coupling,headless-tmux-preserved; renameadvisor-monitored-looptospec-single-owner(#928). - Add
.oh/skills/wiki/scripts/knowledge-impact.sh, the single dependency-aware invalidation primitive:--verifiedfor/wiki lint,--changedfor the/spec executeknowledge gate. (#926) - Add
evals-20260901-suite-tree-cleananddocs-20260901-followup-artifact-cited: no probe may redirect into the repository, and a criterion met by a follow-up must cite its URL. (#926) - Add ten tier-A probes covering the knowledge surface, the planning recall and reconciliation gates, the RUNNING contract, structured completion, and the retired vocabulary. (#926)
- Add
/escalate: an unattended session delivers a human-addressed escalation to the operator's Slack channel. An unavailable channel no-ops loudly rather than failing the session. (#919) - Add
.oh/logs/, gitignored by default with a tracked README, for records that outlive the session that wrote them;/escalateappends every attempt toescalations.jsonl. (#919) - Add
escalate-contract.sh, a tier-A probe: a no-op names its reason, is recorded, and--dry-runmakes no network call. (#919) - Add gate 5 to
/audit implementation: fail a promotable change while its diff can still be smaller. Measures net lines and per-function CCN on changed TypeScript viauvx lizard. (#912) - Add
audit-slop-gate.sh, a tier-A probe holding gate 5's termination contract: a finding needs a concrete smaller alternative, and the loop ends on the cap or a non-reducing round. (#912) - Add
/wiki compile, akind: patterncorpus layer, and an append-onlyskill-impact.mdledger, so a/retrolesson becomes a page/builderreads before proposing. (#916) - Add a
--patternsmode to/wiki querythat filters onkind:, reads up to five pattern entries, and ranks them by term-hit count before recency. (#916) - Add a fault-injection requirement to the probe contract: a probe is not green until its REGRESSION branch has been driven against a broken input. (#916)
- Add capability task
CB-005scoring whether a lesson reaches a validated skill change; two runs score 0.67 then 1.33, moving the suite mean to 1.44 over a changed task set. (#916) - Add
/architect, an inline architecture-decision skill that classifies significance, grounds analysis in repository sources, and returns one Architecture Brief (#929). - Add six tier-A probes covering the
/architectcontract, roles-as-skills, the retired builder agent type, the/delegateworker boundary, the absent agent catalog, and RFC/ADR reuse (#929).
- BREAKING: Move durable repository knowledge to a tracked
.oh/knowledge/surface βsource/,patterns/,raw/tracked,local/ignored β with no compatibility alias. (#926) - BREAKING: Make
/spec planrecall tracked knowledge and re-ground it before the PRD;prd.mdcarries Knowledge Context, Expected Knowledge Impact, and Plan Reconciliation. (#926) - BREAKING: Derive final knowledge impact in
/spec executefrom the actual diff plus page dependencies, resolving every impacted page to UPDATED, REVERIFIED, or NOT-AFFECTED. (#926) - BREAKING: Replace age-based wiki staleness with source-change freshness: a
kind: repopage pinsverified_atand goes needs-review when a declared source changed after it. (#926) - BREAKING: Model
/spec executeas PLANNED -> RUNNING -> READY | DRAFT-BLOCKED(gate), with RUNNING derived fromprd.jsonand mirrored into/tmp/spec-<slug>.state. (#926) - Re-open
/spec execute's promotable gate when a push lands aftergh pr ready: the verdict binds to one head, so a moved head is re-audited or returned to draft. (#926) - Reduce
/wiki lintto six correctness checks and demote/compactto an optional non-gating step that runs only after evidence, retro, and pattern compilation. (#926) - Reduce
/spec retroto an explicit wrapper around/retro --task <slug>, which/retronow accepts;/retrostays report-only and/wiki compilestays the durable pattern writer. (#926) - BREAKING: Move eleven settings out of the compose
environment:block into oh.json, read through theohCLI; a hand-edited.devcontainer/.envno longer carries them (#920). - Make
/specship by default: an unrecognized first token routes to a newshipnode that runsplanthenexecute, so/spec <plan-path>produces a ready-for-review PR (#914). - BREAKING: Persist the sandbox home through one
/home/sandboxmount, not eleven per-tool volumes; setstorage.homePathfor a host path, else<name>_workspace(#898). - Shrink the sandbox image ~540 MB: drop build caches from the baked home seed, stage the seed once via a builder stage, and keep untracked build output out of the build context (#900).
- BREAKING: Stop baking Claude Code, Codex, and Pi into the image; boot installs them into the home mount, so a first boot needs network and runs 60-180s longer (#904).
- BREAKING: Stop baking Herdr and cloudflared into the image; both become
kind: "default"tools installed into~/.local/binat boot from a pinned, checksum-verified binary (#906). - BREAKING: Stop baking OpenCode, Hermes, and Grok Build into the image;
oh harness install <id>installs them into~/.localas the sandbox user (#908). .oh/logs/carries anAGENTS.mdwith aCLAUDE.mdsymlink instead of aREADME.md, matching the directories whose contents are produced apart from the root context. (#924)- BREAKING:
/spec executeno longer launches a coding agent; the agent that runs it is the single implementation owner through the final PR gates (#928). - Task identity and
RUNNINGstate depend on.oh/tasks/<slug>/alone, never on a terminal session, tab, or pane (#928). /delegatekeeps work in the active session when phases share substantial context and spawns provider-native workers only for self-contained, isolated, or parallel work (#929)./spec planjudges architecture significance once and routes a significant topic through/architectbefore planning (#929).docs/glossary.mddefines coding agent, skill, worker/subagent, rule, and RFC/ADR as five distinct terms (#929)./t3launches the headlesst3 serveinstead of the local-GUIt3, and gains--tailscale, apairaction for a second device, and adoctorpreflight (#858).
- Fix
/wiki lintgenerating the corpus index from the working tree instead of the git-tracked set, which made any untracked scratch entry awiki-readme-index.shregression. (#916) - Fix three unresolved
related:and[[slug]]links in therecursive-language-modelswiki entry, and add the/wiki lintcheck that would have caught them. (#916) - Provision the default harnesses into
/home/sandbox/.localat boot, gated byOH_PROVISION_HARNESSES, sooh harness installalso works from inside the sandbox (#902). - Add
oh-home-mount.sh, a tier-A probe holding the single-$HOME-mount contract: one mount per compose file, the baked/opt/home-seed, and the checkout prune that replaces-xdev(#898). - Assert boot-provisioned harnesses in the boot smoke and reject a baked default harness in
verify-sandbox-image.sh, so CI exercises the install path (#904). - Add
oh tool list --defaultsand generalize the boot provisioner over both catalogs asprovision-defaults.sh(OH_PROVISION_DEFAULTS) (#906). - Fix
oh harness installhanging on a sudo password prompt inside the sandbox: every harness now installs as the sandbox user, so no install path needs root (#908). - Add
skills-task-tool-coupling.sh, a tier-A probe holding the canonical skill pack and the sandbox in agreement about the Claude-Code-only task tools (#886). - Add
install.tailscaleandoh tool install tailscale, an opt-in userspace Tailscale client installed into~/.local/binas the sandbox user, granting no capability (#858). - Give the five probes that shipped without one a
# source:header, so every probe records the lesson it closes and thesourcecolumn inRESULTS.mdis fully populated (#889). /delegateno longer instructs the Claude-Code-onlyTaskCreate/TaskUpdatefrom the provider-shared skill pack; its wave graph persists to a.oh/tasks/<slug>/run ledger (#886).
- BREAKING: Retire the
/spec shipnode; an unrecognized first token is an approved plan path that runsplanthenexecute, so/spec <plan-path>is unchanged. (#926) - BREAKING: Retire the generated
.oh/tasks/<slug>/prompt.md; the task prompt is rendered at execution time from its template and never persisted. (#926) - BREAKING: Retire the
STATUS: COMPLETEsentinel; task completion derives fromprd.jsonstory state, which thecleanup-taskscron now reads. (#926) - BREAKING: Move the skill-impact ledger to
.oh/evals/decisions/skill-impact.md; it is a decision record, not a knowledge page. (#926) - Retire orphan detection and the 90-day rule as
/wiki linthealth failures; age survives as informationallast-reviewedtelemetry only. (#926) - Finish retiring
.oh/memoryfrom current architecture docs; the surviving.gitignorerule is labelled a compatibility tombstone with a 0.7.0 removal horizon. (#926) - BREAKING: Retire cron worktree isolation β the
worktree:frontmatter key,.worktrees/cron/per-fire worktrees, theCRON_WORKTREEexport, and every*_WORKTREE*log state are gone; crons fire in the shared root under the id lock. - BREAKING: Retire the
OH_IMAGE_ONLYflag;entrypoint.shdetects the sandbox flavor from whether/home/sandbox/harnessis a bind mount holding.oh/, and logs the detected mode (#920). - BREAKING: Retire
docker-compose.hermes-dashboard.ymland its published127.0.0.1:9119; the dashboard now binds container loopback, reachable over cloudflared or Tailscale (#920). - Remove the duplicate agent-browser and Tailscale installers from
entrypoint.sh; the tool catalog is the sole owner of both pins and Tailscale's two checksums (#920). - Remove the
BAKE_HARNESSESandAGENTSbuild args along with the image bake they gated; the harness catalog is the only source of truth for what gets installed (#904). - Remove Cloudflare's apt repository and its bookworm-suite pin from the image; Docker's is now the only third-party apt source (#906).
- Remove the four optional-harness build args and the dead
buildArgcatalog field; theinstall.*keys keep working and now drive boot provisioning (#908). - BREAKING: Retire the DeepAgents harness β
deepagents-cliis deprecated upstream.install.deepagentsis no longer a settable oh.json field (#910). - BREAKING: Retire Prime Agent and its
.prime/agent/provider surface;oh harness install prime-agentis no longer available (#918). - BREAKING: Retire the
projectRoot/OH_PROJECT_ROOTconfig knob β the checkout is fixed at/home/sandbox/harness, nested inside the home mount (#898). - BREAKING: Retire
.oh/agents/with its.claude/agentsand.codex/agentsprovider symlinks; theohpayload manifest no longer ships anagents/**pack (#929). - BREAKING: Retire
/builder agentand its authoring reference;/buildernow dispatchesskill,command, andruleonly (#929). - Remove the stale
implementer/critic/pm/councilworker types from/delegateand the dangling expert, council, and critic agent paths from/strategic-proposal(#929). - Retire
rl-delegation-write-worker.sh;delegate-worker-boundary.shcarries its read-only-worker lesson forward (#929). - Retire the last
Advisorrole noun from/blog, which told the reader to "use Advisor" for a role that no longer exists; the briefing is/delegate's (#929). - BREAKING: Retire the automated
/specAdvisor handoff β detached tmux launch,agent-spec-*sessions and their sweep kill, pane logging, runner fallbacks (#928).
tsconfig.build.jsonexcluded onlysrc/__tests__/**, soprepublishOnlytypecheckedsrc/lib/__tests__/and failed on the absentvitest, blocking the npm publish after the image had shipped.
oh destroy(a name-typing confirmation,--yesfor non-TTY) andoh compose configclose the last twomake-only verbs, soohis the single lifecycle door (#879).- Tracked
oh.jsonholds every non-secret setting; a gitignored 0600 root.envholds only secrets. Addsoh config show/set,oh secret set/list, and an opt-inoh config repo(#880). - Restore
.oh/agents/as an empty pack with its.claude/agentsand.codex/agentsprovider symlinks; no agent is defined in it (#866).
- Delete the root
Makefile.ohis the only lifecycle door on the host and inside the sandbox, and every verb runs.oh/scripts/docker-compose.shthrough the CLI (#881). - Retire the "host dependencies: Docker, Git, and make β no Node" promise. Host prerequisites are now Docker, Git, and Node >= 20;
get-oh.shinstalls Node when it is missing (#881). - Retire
.devcontainer/.example.env,.oh/config.json,~/.config/openharness/, and theWORKTREES_DIR/PROJECTS_DIR/CRONS_DIRknobs. The layout is now fixed convention (#880). - Delete the
.oh/context/always-on tier in full, leavingAGENTS.mdas the only always-on context. NoSessionStarthook ever loaded it β prose inAGENTS.mdasked for it (#868). - Retire
repo-map-contract.sh,CB-004,repo-orientation/, and its scorer.REPO_MAP.mdgoes as unproven, not disproven: its A/B landed 2026-07-03 and was never run (#868). - Retire the ablation subsystem β
ablate.sh,ablate-state-machine.sh,context-audit-runner.sh,--ablate. Its allowlist took only the five context files (#868). - Retire
CB-003-retro-identity-cycle.mdand theDS-020-lens-diversitydataset, which scored the identity-promotion cycle that no longer exists (#868). - Delete the canonical agent definitions (
.oh/agents/),.oh/plans/,.oh/handoffs/, and the accumulated.oh/tasks/folders and archive (#865).
- Lock the
ohCLI's npm version to the harness release version.ohis the only lifecycle door now, so its version is the only one a user sees, andversion-parity.shkeeps the two package.json files and the CHANGELOG heading in agreement. docs/lifecycle-commands.mdbecomes theoh-only verb reference, and themake ...instructions are swept out ofREADME.md,AGENTS.md, anddocs/(#881).- Collapse the README install fan-out to three paths β npm, the
get-oh.shcurl bootstrap, and from source.docs/intro.mdno longer claims there is no host CLI (#881). - Document the VS Code divergence: "Reopen in Container" applies no compose overlay β no SSH, no docker socket, no Hermes dashboard, no
composeOverrides(#881). - Base the sandbox image on
node:22-trixie-slimand drop the NodeSource vendor script; thesandboxuser is now pinned to-u 1000, the uid the Node image already claims (#878). crons/carries its operating contract asAGENTS.mdinstead ofREADME.md, documenting which cron edits apply at the next fire and which need a SIGHUP reschedule (#874).- Move cron definitions from
.oh/crons/tocrons/at the repo root;oh init/oh updatedeliver them through the manifest's newrootIncludepayload (#874). - Add
CLAUDE.mdprovider-compatibility symlinks beside every nestedAGENTS.mdβ.worktrees/,projects/, andcrons/β created byoh initfor equipped repos (#872). - Move git worktrees to
.worktrees/at each repository's own root and non-harness clones toprojects/<owner>/<repo>/, each tracking only anAGENTS.mdguide (#872). /retrois now strictly report-only and writes no file;IDENTITY.mdwas its only write target. A graduated lesson is nominated as a candidate probe under.oh/evals/probes/instead (#868)./prompt-minerloses itsIDENTITY.mdproposal target and proposes a probe instead (#868).- Rewrite
context-tier-size-budget.shas anAGENTS.md-only 9,500 B ratchet, droppingSINGLE_FILE_SHARE_MAXβ one file in the tier is necessarily 100% of it (#868). - Lower the
capability-benchmark-schemaanddatasets-schemafloors to>= 2, matching the retired CB and DS artifacts (#868). oh initno longer shipscontext/**, so new projects stop scaffolding a directory nothing loads (#868).- Update the
.oh/agents/references indocs/glossary.mdanddocs/oh-directory-layout.mdto describe an empty pack and drop the links to deleted agent files (#867). - Refocus root agent guidance on product identity, glossary, hazards, and code as truth; move build workflow authority into its task skill (#854).
- Upgrade the sandbox base image to
debian:trixie-slimand move Docker's apt suite totrixie; Cloudflare's suite stays onbookworm(#807). - Strip explanatory comments from all tracked code β
.ts/.mjs/.sh/.pyplusoh-path, the Dockerfile, the Makefile and.zshrcβ leaving only machine-read directives (#837).
- Repoint the eight skill surfaces that still cited the deleted
.oh/agents/advisor.md;/delegatenow owns the recursion-budget triple andskill-paths.shguards the dead path (#870). - Amend
rfc-rsi-survey-mapping.md, which still cited the deleted.oh/memory/tier as a live rung-4 instrument and as the harness's capital account (#870). oh harness installandoh tool installnow install live when run inside the sandbox instead of skipping with "sandbox not running";list/statusreport real values instead of?(#861).- The
developmentissue closer never fired:pull_request_targetresolves the workflow from the default branch (main), where the file does not exist. Swapped topull_request(#841). uv python installnow works as thesandboxuser withoutsudo.install -d -o sandbox -g sandbox .../uv/toolschowns the final component only, so the intermediate.../share/uvstayedroot:root.- Root cause detail:
uv python installwrites.../uv/python, a sibling oftoolsinside that root-owned directory, so it failed withPermission denied. Every level is now named explicitly, parents first. - The boot-time ownership repair now covers the uv tree. The UID-sync sweep only rewrites paths owned by the old sandbox UID, so a root-owned uv directory was never repaired. Existing containers self-heal on restart.
ohdetects in-sandbox execution (OH_EXECUTION_TARGET=local|docker-composeoverrides);oh sandboxandoh runtime installrefuse in-box as host-only (#861)..oh/scripts/verify-sandbox-image.shβ reusable image verifier for the base, apt suites, sandbox UID/GID, Node/pnpm pins, the Herdr checksum, and required tool versions (#807)..github/workflows/sandbox-compatibility.ymlβ Dockerfile-scoped CI that builds and verifies arm64 and one amd64 image with every optional installer (#807)..oh/scripts/provision-python.shβ idempotent, user-scoped uv/Python provisioning. Drops from root to the target user withHOMEpinned, installs a managed interpreter and anipykernelvenv, and verifies the kernel.- The script writes
PRIME_AGENT_KERNEL_PYTHONto~/.local/share/oh/python-env.sh, which login shells source. Modes:--verify,--print-env. - Provisioning failures print the exact repair command instead of a bare permission denial, and refuse to suggest
sudo uvβ that installs under/root/.local, unreadable by the agent user. ENV UV_PYTHON_INSTALL_DIRandENV UV_CACHE_DIRpin uv's managed-interpreter and cache trees under/home/sandbox, so nothing falls back to/root.ARG INSTALL_PYTHON_KERNEL=true(withARG OH_PYTHON_VERSION=3.11) bakes the interpreter and kernel venv into the image assandbox, so a fresh boot needs no network.- The entrypoint re-runs the same idempotent script every boot behind
OH_PROVISION_PYTHON(defaulttrue), non-fatally. - Close linked issues on merge into
development:.github/workflows/close-issues-on-development.ymlreads closing keywords from a merged PR and closes each issue (#841). - Add
.github/pull_request_template.mdβ title format, closing-keyword reminder, CHANGELOG checkbox (#841). - Add the
close-issues-on-developmenteval probe: the closer stays merged-only, development-only, and capped atcontents: read+issues: write(#841).
- Remove the standalone
firstmateconcept, runner, prompt, ladder, and active references;/spec executenow owns implementation and gates in one Advisor session (#856). - Remove the default
pi-autoresearchpackage and its integration documentation; Pi no longer reports its conflicting dashboard shortcut at startup (#852). - Remove the
.oh/memorytier entirely. Code is the source of truth. The directory, its trackedREADME.md, theMEMORY.mdledger, and dated session logs are gone as a concept β not relocated. - Remove file logging from the harness. No skill, cron, or script writes a run log under
.oh/. Runs report to the terminal; the only durable trail left is.oh/crons/.cron.log, the cron liveness line. - Remove the seeder
.oh/scripts/ensure-memory-file.sh, its boot pre-create block,MEMORY_DIRfrom both compose files and both.example.envtemplates, and thememoryname from.oh/scripts/oh-path. - Remove
AUDIT_LOG_ROOTentirely. It existed only to resolve a shared log root, soaudit-run.shnow validates and exports one root, androute-driver.shscrubs one fewer variable. - Remove
.oh/skills/retro/references/memory-protocol.md,.oh/skills/retro/scripts/{render-log-entry.sh,memory-audit.py}, and.oh/skills/prompt-miner/scripts/render-log-entry.sh. - Remove the Memory-Improvement-Protocol log step from 20 skills.
oh initno longer seeds.oh/memory/. - Remove 9 eval probes whose subject no longer exists, plus the
probe-memory.mdcontext-ablation probe. See the PR body for the list. - Remove the
workspace/template directory. It held two tracked files (AGENTS.mdand aCLAUDE.mdsymlink) and never was the container's working directory βworkspaceFolderis and stays the repo root. - Remove the Dockerfile
COPY workspace/, theworkspace/**CI path filters, the eightworkspace/*gitignore rules, and theworkspace/README.mdstuboh initused to scaffold. - Remove the
workspacescope from/audit skills;allnow means the root scope alone.
- Default Claude Code to concise replies, no memory of its own (
autoMemoryEnabled+autoDreamEnabled), the harness/gitpolicy instead of the built-in one, and no spinner tips (#834). /retrobecomes report-only. It keeps the scientific pass and promotes only to.oh/context/IDENTITY.mdbehind its propose-then-confirm gate. It writes no log.- A supported
/retrolesson that does not generalize is now reported and dropped; an anti-pattern forbids inventing a file to hold it. The subsystem lens drops from six to five. - Rename
check-memory-duplicates.shtocheck-identity-duplicates.sh; it consultsIDENTITY.mdalone. TheGATE-PENDING/--resolvescontract from #767 retires with the log it wrote. /prompt-minerbecomes report-only.mine-traces.mjsis unchanged apart from its output root; all 36 engine tests pass. Descriptive markers are reported, not promoted./auditreports its run record on stderr instead of appending it to a file, as oneaudit -- run-id=β¦ target=β¦ state=β¦ verdict=β¦ exit=β¦line per outer run./render-html,/prompt-miner,/weigh,/rlm,/audit context --baseline, and wiki drafts write to ephemeral$TMPDIRscratch outside the repo. Nothing under.oh/persists a run..oh/scripts/oh-pathnow resolves every name against the repo root, so_ablate_log_rootand the memory special cases inablate.shandcontext-audit-runner.shgo too.- The heartbeat, cleanup-tasks, eval-weekly, and prompt-miner crons stop logging to memory.
.oh/crons/.cron.logis now each cron's only durable per-pulse signal, andlocked-append.shsurvives as its writer. - Rewrite
heartbeat-logging-contract.shandaudit-run-root-contract.sharound the liveness line and the stderr run record. RetargetCB-003andDS-020fromMEMORY.mdtoIDENTITY.md. - Remove the
conciseness.ymlworkflow. It scoredworkspace/*.mdseeds;SOUL.md/TOOLS.md/USER.md/HEARTBEAT.mdleft that directory ind6751b66, so it has passed on a near-empty set ever since. - Retarget
repo-map-contract.sh's ancestor-helper fixture to.oh/templates/, and move its symlink de-dupe assertion onto the rootCLAUDE.md.
- Remove
harness.yamlentirely. Configuration collapses to.devcontainer/.envplus theohCLI. Deleted:harness.yaml.example,.oh/templates/harness.yaml, the 163-line awk parser.oh/scripts/harness-config.sh, the 251-line.oh/cli/src/lib/harness-yaml.ts, their two test files, theharness-yaml-schema-parityprobe, and themake harness-configtarget. The layer never earned its place: every key it mapped already existed as a compose env var with a default, and it was invisible on the VS Code "Reopen in Container" path, which names.devcontainer/docker-compose.ymldirectly and so reads only.devcontainer/.env. A key set inharness.yamlsilently did nothing there. - Remove the derived
.devcontainer/.harness.yaml.envartifact and the second--env-filethat carried it. The wrapper now passes exactly one env-file β the same one compose auto-loads on the VS Code path β so the two doors cannot disagree by construction.
- Add
.oh/scripts/migrate-harness-yaml.sh: a one-shot automatic migration so no existing install silently loses a setting. It runs from.oh/scripts/docker-compose.shand.oh/scripts/install.sh, so it fires on every lifecycle verb; it translates the 21 allowlisted keys into.env(uncommenting template lines in place), movescompose.overridesinto.oh/config.jsoncomposeOverrides[], renames the file toharness.yaml.migrated, and prints every value it carried over β including both sides of any value it replaced. Absent aharness.yamlit exits 0 immediately. It is self-contained, carrying its own copy of the deleted parser, so the whole compatibility story is one file to delete in a later release. - Add
.oh/cli/src/lib/env-file.tsβ the one.envreader/writer, replacinglib/harness-yaml.ts. Reads go through the existingloadEnvInto, so no fifth env parser was added; writes carry over the uncomment-in-place discipline. Config reads are now plain filesystem reads:oh sandboxandoh shellspawn zero subprocesses to resolve configuration, where every read used to shell out to the vendored parser. - Add three probes replacing the deleted parity probe:
env-schema-parity.sh(the two.example.envtemplates carry the same keys, and every var anydocker-compose*.ymlinterpolates is documented β this closes a real gap:DOCKER_SOCKET,SANDBOX_SSH,SANDBOX_SSH_PORT,OH_SANDBOX_IMAGE,OH_PULL_POLICYandSKIP_PNPM_INSTALLwere consumed but documented nowhere),harness-yaml-migration.sh(append / uncomment-in-place / preserve / overwrite, plus a silent second run), andcompose-config-path-parity.sh(the wrapper path and the VS Code path resolve the same service β the parityharness.yamlmade impossible).
.devcontainer/.example.envis now the schema document, carrying all 25 keys with their defaults and prose, lifted fromharness.yaml.example. Its "Migrated to harness.yaml" block is gone..oh/templates/.devcontainer/.example.envis brought to key parity β anoh initrepo shipped a template documenting three vars.- The installer's config writes always run.
install.shput its entire config block insideif [ ! -f .devcontainer/.env ], so re-running it over an existing install wrote nothing; with.envas the only surface that would have become a total no-op..envis now seeded when absent and the writes always follow, each idempotent and one line wide. Host detections (timezone, git identity) still only seed a fresh file, so a re-run never silently overwrites a hand-edited value. .oh/scripts/docker-compose.shdrops fiveharness.yamlresolution ladders (hermes-dashboard, docker-socket, ssh.enabled, ssh.port, sandbox.name) and thecompose-overridesloop; each collapses onto the.envfallback that was already the next line. The overlay-flist is byte-identical before and after, verified against a recorded baseline..oh/scripts/oh-pathloses itspaths.<name>ladder: the precedence is now<NAME>_DIRenv β.oh/<name>.oh init's wizard writes one file. It used to split non-secret answers toharness.yamland secrets to.env; both now land in.envin a single write, through the same line editor, so the operator's answers appear as uncommented lines inside the documented template.- CI path filters and their probes move from
harness.yaml.exampleto.devcontainer/.example.env(ci-harness.yml,sandbox-boot-guard.yml,harness-ci-core-paths.sh,sandbox-boot-guard-ci.sh).oh-init-headless-config.shretargets to the.example.envtemplate and additionally asserts--yeswrites no.envat all. .gitignorekeeps/harness.yamland.devcontainer/.harness.yaml.envfor one more release so a stale local artifact from a pre-0.4.0 checkout is never committed, and adds/harness.yaml.migrated.
- Remove the
autopilotself-improvement loop entirely: the/autopilotskill, the hourly.oh/crons/autopilot.mdcron (alreadyenabled: false), theautopilot-caps.shPR-cap gate, theautopilot-runseval dataset, and eightautopilot-*probes. The loop had not run in some time and is better rebuilt than maintained. - Remove the
/watchdogskill and its three probes. It existed to babysit autopilot's unattended draft PRs and stuckautopilot-*tmux sessions; with no unattended runner producing them there is nothing to watch.cron-watchdogβ the tmux supervisor that restartscron-systemβ is unrelated and untouched. - Remove
.oh/docs/roadmap.mdand stop/strategic-proposalwriting it. The pinned GitHub roadmap issue is the live surface; the in-repo copy went stale and only cost context to read. - Remove
prompt-miner-caps.sh(both copies), which wrapped the deleted cap gate..oh/crons/prompt-miner.mdis now uncapped and staysenabled: falseβ re-add a cap gate before enabling it; see its Β§ Caps. - Remove the
autopilot:section fromharness.yaml.exampleand.oh/templates/harness.yaml, and theowned-surface-guard,clean-restore, andlocked-append-critical-pathprobes, whose subject was the deleted skill.
-
AGENTS.mdΒ§ The Workflow: the canonical operative path is nowspec-plan β spec-execute β merge β reset|clean. Theselectnode and its designated sole runner are gone β a human enters at/spec plan.workflow-boundaries.shasserts the new shape. -
The harness-infra self-edit surface (
OWNED_PATHS) moves from the deleted skill to.oh/docs/repair-operator-registry.mdΒ§ Tier 1, which is now its source of truth.security-considerations.mdΒ§ 6 is downgraded from ENFORCED to DOCTRINE to say so honestly. -
Capability tasks CB-001 and CB-002 record a baseline reset: pre-0.3.0 scores are not comparable on the
unattendedaxis, since the unattended runner no longer exists. -
Rename the cron runtime's per-cron environment exports to match what they actually are:
AUTOPILOT_REPO->CRON_REPO,AUTOPILOT_REMOTE->CRON_REMOTE,AUTOPILOT_LOG_ROOT->CRON_LOG_ROOT. They are generic plumbing for any cron declaringrepo:orworktree: true, never autopilot-specific, and joining the existingCRON_WORKTREE/CRON_AGENT_BIN/CRON_KEEP_MARKERfamily leaves no vestigial vocabulary behind. Breaking for any out-of-tree consumer that sets the old names β in-tree there are none.
- Add
oh harness <list|install|status>to install optional harnesses into a running sandbox without a rebuild, persisting the choice toinstall.<key>for the next build (#821). - Add
oh runtime <list|install|status>, reporting the container runtime in use and gating a MicroSandbox install on the measured glibc and/dev/kvmblockers. It selects no runtime (#823). - Add
oh tool <list|install|status>for sandbox tooling that is neither an agent CLI nor a runtime, makingagent-browserinstallable without a rebuild behind a ~1 GB download gate (#824). - Add
oh stop|restart|logs|ps, closing the lifecycle gap wheremakehad verbs the CLI did not, and publish onemakevsohmapping doc that the other docs link to (#825). - Document running Open Harness on MicroSandbox by pointing
msbat the published image, and re-scope the microsandbox blockers as devcontainer measurements that say nothing about the reader's host. - Add a "which door am I?" table plus two guard probes:
harness-yaml-schema-parity.shandoh-init-headless-config.sh. - Add
ssh.enabled/ssh.portandsandbox.docker_socketprompts to theoh initwizard, the two settings most likely to need hand-editing. - Require
.oh/tasks/<slug>/evidence.mdbefore/spec executeundrafts a PR, and refuse an untracked one, so the reviewer gets the build's answer back to the plan they approved (#817). - Add a "why this is better" question to the reviewer evidence contract, ahead of the four correctness questions, with unmeasured benefits labelled as such (#817).
- Add
protected-path-deletion.sh, which reads.claude/protected-paths.txtat the merge base and fails when a listed path is deleted without a justification in a committedevidence.md(#817). - Add
memory-probe-claims-resolve.shandcontext-tier-size-budget.shto hold the memory ledger's enforcement claims and the always-on context budget (#817).
- Run
/evalonce per cycle instead of three times:/spec executepublishes a commit-keyedeval-result.jsonthe downstream gates read, cutting 318 probe executions to 110 (#817). - Promote
progress.txtinto the PR body, so the build narrative reaches the reviewer instead of ending at theSTATUS: COMPLETEsentinel (#817). - Write
install.sh's non-secret answers toharness.yamlrather than the lower-precedence.devcontainer/.env, keepingDOCKER_SOCKETin.envas a documented exception. - Lead the README and quickstart with the two scripted installers and demote the untested manual clone sequence into the collapsed section, merging its two duplicate copies into one.
- Match the release-notes heading with
index()instead of a regex built by string concatenation, so extraction does not depend on whether the runner'sawkis mawk or gawk (#820). - Fix the build session launching headless: the prompt travels as argv instead of stdin and no arm carries
--print, so the child no longer answers once and exits (#817). - Stop
| teein the launch path taking the child's TTY; tmux attachespipe-paneafter the pane exists and foreground mode inherits the caller's stdio (#817). - Fix
firstmate.sh --killexiting 1 silently while leaving the session running, the lock claimed, and noFIRSTMATE-INCOMPLETEline appended (#817). - Stop the
/auditboundary exporting its lifecycle identity to the agent it launches, which made probes grade their caller and flipped one tree's verdict between runs (#817). - Rewrite 76 unbacked
probe:claims in the memory ledger to explicitprobe: nonevia a tracked idempotent script (#817). - Correct the MicroSandbox runner walkthrough: set
entrypoint:explicitly, without which the seed and provider linking never run; drop the unsubstitutedGH_TOKEN; and re-rank the untested inferences so the boot-breaking one leads. - Collapse the two disagreeing
harness.yamlline editors into onesetKeyInSectioninlib/harness-yaml.ts; the wizard's section-blind copy silently dropped answers for keys absent from the template. - Reconcile
.oh/templates/harness.yamlwithharness.yaml.example, restoring thesandbox.docker_socket/image/pull_policy,paths.worktrees,crons,autopilot,slack, andcomposekeys that had no home to be written into. - Correct
harness.yaml.example's claim thatpull_policyreaches the VS Code "Reopen in Container" path β it does not, and no key in the file does.
- Remove the critique/approve gate; the operator's approval of
prd.mdis the commitment gate, and no critic agents are spent per plan (#817). - Collapse three build executors to one, deleting
.oh/scripts/ralph.shand every executor toggle rather than reducing them to a single accepted value (#817). - Absorb
/ship-specinto/spec executeand delete the skill, so the build mechanics read top to bottom in one file with no deferral (#817). - Delete
.oh/prompts/,.pi/prompts/advisor/, and the First Mate charter, leaving.oh/skills/firstmate/templates/session-prompt.mdas the only description of the build workflow (#817). - Delete
/teachand its pipeline step;evidence.mdcarries the model to the reviewer, and the wiki half was already a gate in step 5 (#817). - Delete the DeepWiki comparison from the wiki gate, which regenerates on no schedule the gate can depend on, and rename the schema section to state its own requirements (#817).
- Delete four
STATUS: SPEC-*tokens with no executable consumer and drop the groom triad from the per-cycle path (#817).
- Emit
scoreUncappedalongside the clampedscorein/prompt-miner, and report asUNSTABLEany marker whose capped and uncapped effect sizes disagree (#778). - Anchor the
memoryname inoh-pathto the main worktree (#152, #693, #768). - Make
/retroappend aGATE-PENDINGlog entry before the approval gate and a resolving entry with the real counts after it (#767). - Make the
/stechecker's exit-0line name the two defects it cannot see β a condition placed after the action it guards, and a sentence opening on a pronoun with no antecedent β and point atSKILL.md. - Keep the firstmate execution-context probe pane alive across its own read, so the runner gate can admit herdr instead of refusing it in every environment (#761).
- Make assertion (d) of
cc-safety-net-wiring.shassert the resolved cc-safety-net version instead of the declared dependency range (#759). - Repair seven
.claude/protected-paths.txtentries that resolved to nothing and add a probe so a rename cannot silently disarm a guard again (#753).
- Pin transitive
nanoidto the patched^3.3.17range to close GHSA-2v37-7h3g-55p8 through the Vitest β Vite β PostCSS dependency path. - Deny the
docker/podman/nerdctlinspect shapes that expose environment variables β any template namingenvor expanding the whole object β while keeping narrow field reads (#723). - Block agent reads and writes to operator-owned
settings.local.jsonfiles across Claude, Codex, and shared Open Harness hooks (#710).
- Remove the
/cavemantoken-compression skill and its four subcommands after 743 session traces showed zero invocations (#752).
- Add
.oh/docs/rfcs/rfc-rsi-survey-mapping.md, a decision-only RFC mapping a recursive-self-improvement survey onto this repository (#525). - Add
.oh/scripts/registry-portability.shand two portability probes (#758, #645, skills#7). - Add
/ste, a Simplified-Technical-English standard for artifact prose: 53 rules, a 198-word dictionary, 24 examples, and a dependency-freeste-check.sh(#750). - Add
firstmate, an opt-in third build executor (--executor=firstmate) running one long-lived session over a whole.oh/tasks/<slug>/graph (#746). - Add
.oh/docs/rfcs/rfc-brain-hands-boundary.mdas the authoritative Phase-0 brain/hands contract (#733, Refs #731). - Record the audit's proof as a committed
.oh/tasks/<slug>/evidence.mdduring the.oh/prompts/advisor/pr.ymlflow (#719). - Deny agents read and write access to the operator-only
.config/directory, at the repo root and in$HOME, as a first-class tier in bothPreToolUseguards (#707). - Add
lsof,htop, and theinetutils-telnetplaintext diagnostic client to the default sandbox image (#703).
- Release versioning moves from CalVer to SemVer. Root
package.jsonnow holds the only copy of the version, and an unbumped push tomainis a clean no-op run instead of a failure (#814). - Rehome
/health-checkDocker triage host-side (#762, Refs #756, #731). - Ship
.oh/docs/**through the payload manifest while retaining the.oh/patches/**exclusion (#738). - Retire the five
KNOWNentries from.oh/scripts/registry-portability.md, leaving 8ALLOWentries and a clean lint (#758, #751). - Route
oh sandboxandoh shellthrough theExecutionTargetcontract with no operator-visible behavior change (#733, Refs #731). - Enable Pi subagent FleetView by pinning
@tintinweb/pi-subagents@0.12.0, with the navigable agent list on by default. - Set the default Pi driver to
openai-codex/gpt-5.6-lunawithmaxreasoning while retaining Sol, Terra, and Luna in the model selector (#700). - Release every validated push to
mainormasterwith retry-safe CalVer reservations, immutable GHCR tags,latestdigest promotion, gated CLI publication, and Release finalization (#689). - Expose the supported GPT-5.6 variants in Pi's model selector (#684).
- Expand Advisor planning with a designer lens and make implementation/PR prompts explicitly finish with delegated audits and retrospectives (#680).
- Install the pinned
ryaneggz/pi-langfusecommit carrying the upstream shutdown fix (gooyoung/pi-langfuse#14, #715). - Stop the cron reaper from reading a
git statusfailure as uncommitted work, adding aWORKTREE_ORPHANEDoutcome that removes the orphaned directory (#694). - Resolve the
prompt-minerdaily-log write root to the main worktree viaAUTOPILOT_LOG_ROOTβCRON_WORKTREEβ toplevel, so Step 5 entries survive the cron reaper (#693). - Admit sessions whose activity span overlaps the
prompt-minerwindow, exclude subagent turns from every signal, and widen the daily cron window to--hours 336(#692). - Make the
prompt-minerengine run through the.claude/skillssymlink with a symlink-safe entrypoint guard (#692, #663). - Index
.oh/docs/rfcs/rfc-runtime-support.mdfrom.oh/docs/README.mdand repoint the dangling.claude/rules/bullet in thecriticandimplementeragents (#686). - Declare
/help,/trusted,/channels,/enable,/disable,/revoke, and/toggletoolsin.pi/install/slack-manifest.json(#354).
- Install Herdr by default as a persistent multi-agent terminal workspace (#651).
- Add bounded local PDF, DOCX, PPTX, and XLSX normalization to
/wiki ingestthrough Microsoft MarkItDown's pinned CLI, preserving immutable source provenance (#650). - Add the explicit nine-target
/auditdispatcher, deterministic focused/queue PR classifier, correlated full campaigns, and shared locked ablation recovery (#646). - Adopt
cc-safety-net@1.0.6as the destructive-command guard for claude, codex, and pi, baked into the image with aCC_SAFETY_NET_OFF=1kill-switch (#654). - Add the First Mate role charter at
.oh/context/rules/first-mate.md, the git-tracked.oh/prompts/advisor/prompt pack, and anarchitectcrew agent (#660).
- Default agent-browser desktop sessions to a 1280Γ720 viewport (#674).
- Refresh the default Claude model, durable review-loop guidance, and Cloudflared public-surface verification instructions (#672).
- Relicense from MIT to Apache License 2.0 with patent grants and trademark clarity; prior MIT releases remain available under MIT and the hosted Console stays proprietary (#666).
- Make Herdr the canonical first interactive workspace after sandbox entry, with setup and agents organized inside persistent panes and a pinned, checksum-verified CLI (#653).
- Protect the consolidated
/auditowner in place of the supersededharness-audit,skill-lint,eval-lint, anddrift-checkentry points (#647). - BREAKING: Consolidate artifact authoring under
/builder <agent|skill|command|rule> <name-or-request>with one authoritative reference per type (#643).
- Harden audit consolidation with real GitHub CI normalization, executable run/log lifecycle, focused watchdog classification, and non-mutating implementation gates (#646).
- BREAKING: Remove the superseded audit-family entry points and the
auditoragent; migrate/pr-audit,/harness-audit,/skill-lint, and peers to their/auditsubcommands (#646). - Remove the legacy
agent-builder,skill-builder,command-builder, andrule-builderagents and the superseded/skill-builderentry point; migrate callers to/builder(#643). - Retire the dead
RISKY_BASHarray and its bash branch from pi's.pi/extensions/path-guard.ts, now superseded by cc-safety-net;SENSITIVE_PATHSand/guardare retained (#654).
- Add a reproducible, audit-gated
pi-langfuse@1.5.7installer that overrides its vulnerable OpenTelemetry SDK tree to patched@opentelemetry/sdk-node@0.220.0(#664). - Pin the transitive
postcssdependency to the patched^8.5.18viapnpm.overrides, clearing GHSA-r28c-9q8g-f849 and unblockingpnpm run security:auditon every PR (#668). - Move every pinned GitHub Action off the deprecated Node 20 runtime and unpin the major in the
pnpm-audit-ci-gateprobe so future runtime bumps do not read as regressions (#670).
- Keep
/tmp/cron-watchdog.shroot-owned and make the optional cron supervisor non-fatal underset -e, so a container restart no longer crash-loops the node (#640).
- Document optional Pi-to-Langfuse observability, configuration precedence, privacy controls, and sandbox network boundaries (#480).
- Document optional Claude Code-to-Langfuse observability through the official marketplace plugin, including the user-scope privacy boundary and local sandbox endpoint setup (#480).
- Make
/delegateinherit the session model by default and select the Agent tool'sthinkinglevel from task complexity (#637).
- Pass
--ignore-registry-errorsto thepnpm auditpreinstall hook so npm's retired audit endpoint (HTTP 410) no longer abortspnpm installon fresh sandbox boots (#639).
- Add
oh cloudcommands for securely storing the current provisioner credential and managing OpenHarness Cloud SSH keys and node lifecycles without hand-written API requests (#625). - Add an opt-in sshd compose overlay with loopback binding, public-key-first auth, host-port collision checks, and direct-SSH/nginx multi-tenant docs (#599).
- Route
/delegateworker selection through version-agnostic Luna, Terra, and Sol tiers with compatible legacy fallbacks (#627).
- Fix the
OH_IMAGE_ONLY=1(no-bind) boot crash-loop by re-including the tracked.claude/control-plane config in.dockerignoreand self-healing already-seeded volumes that are missing those files.
- Remove the Railway hosted smoke deployment surface, including the root Railway config, deploy assets, documentation, README button, and eval guard.
- Move the canonical ignored worktree root into
.oh/worktrees/, includingWORKTREES_DIR/paths.worktreesplumbing and updated runtime/docs/skill references.
oh sandboxcan pull the published GHCR image instead of rebuilding locally. Adds--image[=<ref>],--no-build,harness.yamlimage/pull-policy wiring, docs, and an eval guard (#610).- Open Harness can run in image-only mode without a repo checkout. Adds
docker-compose.image-only.yml,OH_IMAGE_ONLY=1volume seeding from/opt/oh-seed, and an eval guard (#611). @mifune/openharnessnow ships a README and LICENSE on its npm page. Adds.oh/cli/README.mdand.oh/cli/LICENSEand bumps the CLI to0.1.1(#564).
- Move the
ohCLI npm publish into its ownpublish-cli.ymlworkflow, triggered byworkflow_dispatchand CalVer tags, so a CLI-only change can publish without a harness release (#564).
- The CLI's
prepublishOnlytypecheck no longer needs workspace-root test dependencies: it now usestsconfig.build.json, which excludessrc/__tests__/**(#564).
- The
publish-npmCI job now publishes the CLI from.oh/cliinstead of the repository root, so thedist-only bundle ships instead of the private root package (#564).
- The host Docker socket is no longer mounted by default β it is now an explicit, prompted opt-in. Enable it with
sandbox.docker_socket: trueorDOCKER_SOCKET=trueto apply the docker-sock compose overlay.
- Equipped-project sandbox no longer crash-loops on boot.
link-providers.shnow falls back to${OH_PROJECT_ROOT:-$PWD}when the project is not a git checkout, instead of failing the entrypoint.
- Publish the standalone
ohCLI to npm as@mifune/openharness, so Node.js β₯ 20 users cannpm install -gornpxit instead of theget-oh.shbootstrap (#564). - Add
.oh/scripts/get-oh.sh, a curl|bash installer that puts the self-containedohbinary in~/.local/bin/ohwith no repo clone, offering nvm + Node 22 when Node.js β₯ 20 is missing. - Add ADR-0001 recording #532's disposition: the lightweight RFC/ADR convention is sufficient, and taxonomy, registries, lifecycle, and conformance stay deferred (#532).
- Add a descriptive, example-only
.oh/harness.ymlmanifest reference pointing at today's.oh/agents/,.oh/skills/,.oh/hooks/,.oh/crons/, and.oh/tasks/surfaces (#532). - Add
.oh/docs/rfcs/rfc-selfimprove-roadmap.md, a curated self-improving-harness roadmap decomposing the epic into dependency-ordered proposed child issues for human filing (#525). - Add
.oh/docs/rfcs/rfc-trace-ledger.md, an RFC for an append-only normalized trace/event ledger with proposed.oh/traces/and.oh/sessions/storage, redaction rules, and event set (#525). - Add the
oh-cli-portable-lifecyclewiki entry on the standalone CLI's payload precedence and lifecycle verbs, plus a "Standalone CLI (oh)" section in.oh/docs/installation.md(#564). - Add the
oh-standalone-lifecycleeval probe guarding thesandbox/shell/gateway+--from-remoteregistrations and the consumer/home/sandbox/projectpath mapping (#564). - Add
oh sandbox,oh shell, andoh gatewaylifecycle verbs β wrappers over the vendored.oh/scripts/that resolve the equipped-project root from any subdirectory (#564). - Add
.oh/docs/security-considerations.mddocumenting the security boundaries the harness enforces today, each path-cited to its mechanism and labelled ENFORCED vs RECOMMENDED (#568). - Add a lightweight RFC/ADR index at
.oh/docs/rfcs/README.md:RFC:/ADR:issues moving Draft β Accepted β Superseded (#532) (#567). - Add an agent-browser X.com login snippet for dashboard-observed human login, persistent profiles, 2FA/CAPTCHA handling, Google OAuth fallback, and credential safety.
- Add a Railway one-click hosted smoke deploy path from the README, with config-as-code, deploy assets, docs, and an eval drift guard (#553).
- Add the
OH_PROJECT_ROOTproject-root seam as the single source of truth for the container workspace path (default/home/sandbox/harness), withHARNESSkept as an alias (#531). - Add
oh init [dir]to scaffold a fresh harness checkout from a.oh/templates/payload, with a--templates <dir>escape hatch and theoh-init-scaffoldeval probe (#531). - Add
oh update, which upgrades only the.oh/control plane of an equipped repo from a--from <checkout>source, leaving project source untouched (#531). - Add
.oh/manifest.json, a payload manifestoh updatehonors so it overlays a declared allowlist and no longer vendors.oh/docs/or.oh/patches/(#531). - Add two Recursive Language Model skills β
/weigh(weighted-trajectory scoring) and/rlm(context-as-environment decomposition), plus two eval probes (#533). - Teach
oh init/oh update--from-remote [--ref <ref>]to materialize the payload and templates from a shallow clone of the public repo (#564). - Add
.oh/docs/oh-directory-layout.md, a descriptive map of every real.oh/top-level entry with its purpose and canonical consumer, linked from the docs index (#566). - Add a descriptive
.oh/docs/glossary.mddefining Open Harness's core vocabulary as the repo uses each term, with a canonical source pointer per entry (#565). - Add
rfc-runtime-support.mdwith the runtime-support taxonomy and contract for epic #591, plus two wiki entries (#592).
oh init-scaffolded sandboxes now mount the workspace at/home/sandbox/harnessinstead of/home/sandbox/project, matching the harness's own devcontainer.get-oh.shcan now be run withsource <(curl β¦ )to install and putohon the PATH in the current shell, and prints the same-shellexport PATH="$HOME/.local/bin:$PATH"instruction.- Improve
/health-checkperformance by caching baseline snapshots, gating verbose Docker/process probes, and reusing one-pass diagnostics for ranked reclaim reports (#576). - Resolve the #532 RFC-index disposition as accepted-lightweight, cross-linking ADR-0001 and keeping the standards-body scope deferred (#532).
- Clarify the glossary's model / agent CLI / harness / loop / policy / trace layer separation without introducing conformance machinery (#532).
- Clarify the #525 docs/RFC indexes so the roadmap curation and trace/event ledger RFC are discoverable (#525).
oh init's "Next steps" now recommendsoh sandboxandoh shell, keeping rawdocker composeonly as a parenthetical fallback (#564).- Replace the
/advisorskill with anadvisoragent at.oh/agents/advisor.mdthat returns the 5-field delegation briefing for the caller to hand off, with every reference to the deleted skill repointed in lockstep. - Treat root
harness.yamlas local gitignored state generated from trackedharness.yaml.example;make harness-configcreates it on demand andmake sandboxruns that guard before building. - Consolidate the harness's own devcontainer back into the conventional root
.devcontainer/, superseding the.oh/devcontainer/relocation from this same unreleased cycle and retiring thesync-devcontainer.shcompat generator. - Relocate the Ralph/spec task workdirs from
tasks/to.oh/tasks/with no back-compat symlink, repointing the git-mutating consumers directly (#531). - Relocate the Ralph/spec cron definitions from
crons/to.oh/crons/with no back-compat symlink, repointing every consumer including theCRONS_DIRdefault. - Relocate the fitness-function eval suite from
evals/to.oh/evals/with no back-compat symlink, repointing the runner walk-up, all 68 probes'ROOT, and the benchmark scorer'srepoRoot. - Relocate the harness's long-term memory and session logs from
memory/to.oh/memory/with no back-compat symlink; tracked files move and the gitignored dated logs stay ignored at the new path. - Relocate the always-on identity core from
context/to.oh/context/with no back-compat symlink, repointing theAGENTS.md/CLAUDE.mdsession-start reads, protected paths, and the affected probes and benchmarks. - Route hardcoded
/home/sandbox/harnesscontainer-path literals in the devcontainer layer and.oh/scriptsthrough${OH_PROJECT_ROOT:-/home/sandbox/harness}(#531). - Relocate the harness's devcontainer build assets to
.oh/devcontainer/, leaving root.devcontainer/as a thin generated compat layer (#531). - Absorb the shared primitive pack into
.oh/, retiring the.mifunesubmodule β skills, agents, and hooks are vendored under.oh/and shipped in the payload, sooh init/oh updateneed no submodule fetch. - Move the rendered Docusaurus docs site and blog archive to
mifunedev/openharness-web; the core repo now points readers todocs/README.mdand DeepWiki (#536). - Dedupe Docusaurus-site leftovers after the
openharness-webmove by stripping dead frontmatter fromdocs/**/*.mdand dropping stale in-repo docs-site references (#536 follow-up). - Relocate the GitHub-readable markdown docs from
docs/to.oh/docs/and repoint every live pointer;oh updatestill excludes them from equipped repos (#536 follow-up). - Default the build executor to ralph β Stage 10 launches
.oh/scripts/ralph.shand watches forSTATUS: COMPLETE;/delegatebecomes optional fan-out (ryaneggz/openharness#338).
- Make Hermes gateway startup repeatable by pinning
HERMES_HOME/terminal.cwdto the harness checkout and self-healing Microsoft Teams webhook dependencies. - Refresh the devcontainer root
pnpm installgate when package manifest inputs change, preserving fast boot when dependencies are current (#521). - Cron runtime entries now store canonical absolute source paths, so body hot-reload keeps working after cwd changes instead of logging
BODY_RELOAD_ERRand using stale cached prompts (#517). - Release publishing now smoke-tests the locally built sandbox image before pushing GHCR tags, ensuring the published release image boots and passes the sandbox healthcheck first (#515).
- Remove obsolete top-level
wiki-ingest,wiki-query, andwiki-lintskill directories, preventing Pi startup from reportingdescription is requiredon reference-onlySKILL.mdfiles.
- Remove the in-repo
.oh/docsDocusaurus package, docs deploy workflow, docs build scripts, and docs-only pnpm dependency graph from Open Harness core (#536).
- Patch Dependabot security alerts for
dompurify,http-proxy-middleware,undici, andwebpack-dev-servervia pnpm overrides and lockfile refresh (#527).
- Restore the GitHub Pages docs workflow after the docs app relocation by pointing the build and artifact paths at
.oh/docsand guarding the path indocs-build-fast-path.
- Add the
/syncdispatcher skill withpublish,catchup, andstatussubcommands for gated originβupstream synchronization, plus topology docs and thesync-skill-contracteval probe (#526). - Forward-sync
ryaneggz/openharness:developmentintomifunedev/openharness:development, bringing theauditoragent,.oh/grouping, and/spec+/wikiconsolidation (ryaneggz#327). - Add the
/t3skill to start, inspect, and stop T3 Code (npx t3) in a sandbox tmux session, with pairing-URL discovery and log/status helpers (#509). - Add the
/prompt-minerskill andmine-traces.mjsengine to score session traces, rank initiating prompts, and mine prompt markers behind a confirm gate (#503). - Enable Pi
ffffile search by default, pinningnpm:@ff-labs/pi-fff@0.9.5forffgrep/fffindand@-mention autocomplete while keepinggrep/findas fallback (#499). - Add the
autopilot-merged-pr-reference-dedupeeval probe guarding that/autopilotskips completed-but-still-open tickets whose development PRs already merged (#468). - Codify the canonical operative path in
AGENTS.md Β§ The Workflow(select β spec-plan β spec-critique β spec-execute β merge β reset|clean), guarded by theworkflow-boundariesprobe (#493). - Add the
spec-*skill family (/spec-plan,/spec-critique,/spec-execute,/spec-retro) decomposing/ship-specinto folder-pointed nodes, guarded byspec-family-contract(#493). - Codify the advisor-monitored ralph-loop variant in
context/rules/advisor-model.md, guarded by theadvisor-monitored-loopeval probe (#493). - Add
context/REPO_MAP.mdgiving session-start agents a source-map command plus keep/disregard paths, guarded byrepo-map-contractand the CB-004 benchmark manifest (#464). - Ship
pi-dynamic-workflowsas a default project-local Pi package pinned to upstreamv1.0.1, with docs for theworkflowtool's fan-out model and package-pin tests (#451). - Add the
heartbeat-logging-contracteval probe guarding that heartbeat runs keep structured memory logs and locked liveness appends (#447). - Add the
sandbox-boot-guardCI workflow validating sandbox compose config and locally building the devcontainer image for boot-path changes, guarded bysandbox-boot-guard-ci(#449). - Add the
retro-deterministic-contracteval probe guarding/retroschema-backed output, self-contained helpers, and synchronized.pi/.claudeskill copies (#443).
- Clarify oh.mifune.dev copy so "harness" means the repo and "agent" means the CLI, stating one-repo-per-sandbox, tracked state, and sandbox isolation across the site and docs (#466).
- Move the shared skill source of truth from
.claude/skills/to.mifune/skills/, with.claude,.codex,.pi, and Hermes now symlinking to it and CI path filters updated (#501). - Skip the Pi path-guard risky-bash confirmation in interactive TUI sessions while keeping sensitive-path write prompts and all headless/cron/autopilot confirmations (#495).
- Replace the in-tree Slack Pi extension with the
pi-messenger-bridgenpm package, loaded only in theclient-slacktmux session (#481). - Run docs builds only from the docs workflow on
main/masterpushes, keeping root build, Harness CI, release validation, and/evalon the fast non-docs path (#455). - Clarify docs copy on product framing (one developer, one project, one agent) across the intro, installation, harnesses overview, and landing pages (#493).
- Give
/retroa report schema plus skill-local helper scripts for deterministic hypothesis validation, duplicate-memory checks, and log rendering (#443).
- Hash canonical absolute append targets in
scripts/locked-append.shso relative and absolute spellings of the same log serialize through one lock (#513). - Re-inject non-Slack Pi turns once on the Codex
previous_response_not_founderror via an auto-loaded.pi/extensions/codex-stale-response-retry.tsextension (#506). - Re-enable the default
@narumitw/pi-codex-usagePi package at0.6.2, restoring/codex-statuswithout the replacement-context crash (#419). - Preserve dirty, untracked, unpushed, or suspicious stale worktrees during weekly cleanup instead of deleting by age alone, with eval coverage for the gate (#478).
- Route cron runtime and weekly cron prompt liveness
.cron.logwrites throughscripts/locked-append.sh, extending the locked shared-log contract beyond autopilot and heartbeat (#474). - Preserve path-qualified cron file paths on fire-time metadata reload, preventing body hot-reload from falling back to stale cached prompts with
BODY_RELOAD_ERR(#472). - Skip open tickets with merged PR references in
/autopilotissue selection, avoiding duplicate rebuilds whenCloses #Nlanded but GitHub left the issue open (#468). - Use temporary
harness.yamlenv files for compose helper diagnostics so--print-argvandconfigno longer overwrite.devcontainer/.harness.yaml.env(#470). - Route
/context-auditand/health-checkMemory Protocol examples throughscripts/locked-append.sh, guarded bymemory-log-locked-append(#476). - Make
/prdconsistently write PRDs totasks/<feature-name>/prd.md, guarded by theprd-output-path-contracteval probe (#483). - Boot the built sandbox image and verify the in-container healthcheck in the sandbox boot guard, catching entrypoint regressions in CI (#485).
- Post Slack bot replies in a thread anchored to the triggering channel message (group chats only, so DMs stay flat), temporarily pinning the bridge to a fork branch carrying the patch (#481).
- Run the
client-slackbridge under a self-healing supervisor (.devcontainer/client-slack-supervise.sh) that restarts pi on the stale-ctx failure and on crashes (#481). - Run the
client-slackbridge attached to the tmux pane's TTY instead of--mode rpc β¦ | tee, eliminating theextension_ui_requestJSON flood while capturing logs out-of-band (#481). - Add a standalone
.pi/bridge-recovery/extension that re-injects a failed Slack-originated turn once on the Codexprevious_response_not_founderror (#481). - Preserve a live early-run tmux session whose name matches its cron worktree basename during cron worktree pruning, keeping active autopilot checkouts alive before branch rename (#445).
- Compute memory-log timestamps explicitly in heartbeat instructions and route memory and liveness writes through
scripts/locked-append.sh(#447). - Stop stale legacy
system-crontmux sessions at devcontainer boot before startingcron-watchdog/cron-system, avoiding unhealthy migrated sandboxes (#453). - Seed
~/.pi/msg-bridge.jsononly when absent and otherwise jq-merge it, so container boot no longer clobbers the operator'sauth.trustedUsers/auth.channelstrust grants (#493).
- Remove stale Pi authentication and port-forward docs now that Pi supports device auth (#528).
- Remove the deprecated executable-loop framework β
context/rules/loop.md, the/orchestrateskill, and four loop-coupling probes β leaving the former loop-node skills standalone (#497).
- Default
/post-bridgepost creation to draft/dry-run previews and requirePOST BRIDGE LIVE CONFIRMEDbefore live or scheduled publishing (#523). - Keep Slack token values out of the tmux command string on
client-slackrestore by sourcing a permission-restricted runtime env file before launchingpi(#461).
pr-audit-duplicate-issue-refseval probe guards that/pr-auditkeeps duplicate open-PR issue references visible as a read-only triage flag (#439).harness-auditwiki entry and Context Snapshot memory load-status diagnostics preserve the shared-memory model salvaged from duplicate #432 PRs (#441).autopilot-open-pr-reference-dedupeeval probe guards that issue selection checks open PR metadata, branch names, titles, and bodies before launching duplicate autopilot work (#437).- Add the
harness-audit-shared-memoryeval probe guarding that/harness-auditreads durable memory fromAUDIT_LOG_ROOTin cron worktrees (#432).
- Document a duplicate issue-reference flag in
/pr-auditso open PRs closing the same issue are grouped for human canonical-PR selection (#439).
- Dedupe autopilot issue selection against open PR metadata, branch names, titles, and bodies before starting work, preventing repeated PRs for the same issue (#437).
retro-deterministic-contracteval probe guards that/retrokeeps schema-backed output, self-contained helper scripts, and synchronized.pi/.claudeskill copies (#443).
- Sync
ryaneggz/openharness:developmentchanges aftere863676into canonical development, including Pi autoresearch support, cron/watchdog hardening, and Slack startup fixes (#430).
- Add the
/gitskill promoting the formercontext/rules/git.mdconventions into a provider-portable command skill (#422, #424). - Replace the autopilot-specific watchdog with the generic
/watchdogstuck/stale automation skill, whose first action completes stale autopilot draft PRs and removes draft only after verification. - Add the
autopilot-upstream-defaulteval probe guarding that/autopilotand/ship-specdefault GitHub/git operations to upstreammifunedev/openharnessviaupstream/development. - Add the
/teachskill, a post-implementation pass that revises the wiki model then teaches the operator the mental model, evidence, and caveats (#214). - Add the tokenmaxxing Open Harness blog post explaining frontier-token spend as a harness-building pattern, not a productivity leaderboard (#212).
- Add
wiki-ingestGitHub-repo-study and social-image research patterns with a worked example, route three crons toagent: pi, and add/ci-statusand/pr-audittriage guidance (#208). - Add
scripts/locked-append.shto serialize shared-runtime-log writes withflock, route autopilot/caps appends through it, and guard it with a probe (#204). - Add a deterministic
preflight:cron field runningscripts/autopilot-caps.shbefore any worktree, tmux, or agent is created, so a capped hour logsSKIPPED-CAP-*and spawns nothing (#194). - Ignore
js-yamlfor Dependabot security updates in.github/dependabot.yml, since its fix is unreachable through the Docusaurus dependency chain and the job failed every retry (#200). - Add the
evals/datasets/verifiable trajectory corpus of real issueβshipped-PR trajectories with provenance, prompt, oracle, andverify.sh(#196). - Wire the executable-loop
benchmarknode with a new/benchmarkskill composing/evaland the capability-benchmark ceiling delta into a verdict (#179). - Add the capability benchmark instrument (
evals/capability/) as the harness progress ceiling, with a spec, three seed tasks, and a baseline scoreboard (#167). - Wire the executable-loop
repeatnode with itsCYCLE-CONTINUEtoken, applied by/orchestratevia--max-itersand caps (#173, #175). - Add the
/orchestrateskill, a standalone walker of the executable-loop decision tree with STATUS-tail routing,--dry-run/--start/--max-iters, and honest halt at unwired nodes (#160). - Wire the
compressloop node so/context-auditemitsSTATUS: COMPRESS-DONEβbenchmark(#160). - Add the
orchestrate-contracttier-A eval probe guarding the/orchestratecontract literals (#160). - Wire the
implementnode by giving/delegatea## HandoffemittingSTATUS: IMPL-COMPLETEβauditorIMPL-INCOMPLETEβimplement(#156). - Add the
/critiqueskill running two adversarial critic agents againsttasks/<slug>/prd.mdand writing SEVERITY-tagged findings totasks/<slug>/critique.md(#156). - Add the
/approvedecision gate that readstasks/<slug>/critique.mdand emitsSTATUS: APPROVEDβimplementorDENIEDβplan(#156). - Add the read-only
/auditper-unit verdict gate composing task-graph conformance,/eval,/pr-audit, and/agent-browserinto a pass/fail verdict (#156). - Add the
loop-handoff-consistencytier-A eval probe guarding that every skill's## Handoffemits aSTATUS:token known tocontext/rules/loop.mdΒ§ 2 and routes only to real loop nodes. - Add
context/rules/loop.mdas the single source of truth for the executable harness loop, defining theSTATUS:terminal-status convention, the per-skill## Handoffconvention, and six load-bearing invariants. - Trigger Harness CI on
Makefileandharness.yamlchanges, guarded by theharness-ci-core-pathseval probe so core sandbox config path-filter coverage cannot silently drift (#165). - Add
scripts/sandbox-healthcheck.shverifyingcron-watchdog/cron-systemand configured Slack/Hermes sessions, with docker-compose reporting failures through container health status (#150).
- Give
/retroa report schema plus skill-local helper scripts for deterministic hypothesis validation, duplicate-memory checks, and log rendering (#443).
/ship-specnow compacts around implement, hands the build to a worktree Advisor in a tmux session, and undrafts the PR only via a/pr-auditpromotable gate (#140).- Add the
ship-spec-ready-finalizationprobe guarding that/ship-spectreats the draft PR as a checkpoint and ready-for-review as the terminal state (#134). - Add the
autopilot-pi-agenteval probe guarding that theautopilotcron setsagent: piand thatcron-runtimehonors per-cron agent overrides (#116). - Add the
autopilot-executor-toggleprobe guarding/autopilot's default executor, Ralph fallback,/goalphrase, session naming, and non-mutating dry-runs. - Pin
npm:@tifan/pi-recap@0.4.2in.pi/settings.json, adding/recapplus automatic idle/resume session recaps for long-running Pi sessions (#138). - Pin
npm:@narumitw/pi-codex-usage@0.4.2in.pi/settings.json, adding/codex-statusand anopenai-codexstatusline for 5-hour and weekly usage (#108). - Pin
npm:@tintinweb/pi-tasks@0.7.0in.pi/settings.json, adding the/tasksmenu and persistent task widget and ignoring.pi/tasks/runtime state (#105). - Add an independent
eval-probesCI job that runs the probe suite on every PR and push todevelopment/main, failing the pipeline on a new greenβred regression (#103). - Add the
drift-check-cron-staleness-globprobe, which runs/drift-check's live Step C-2 block against fixtures to pin the schedulable-cron predicate (#98). - Pin
npm:@narumitw/pi-goal@0.4.2in.pi/settings.json, adding the/goalcommand andgoal_completetool to Pi sessions by default (#97). - Add a
SIGHUPhandler toscripts/cron-runtime.tsthat re-reads everycrons/*.mdand re-arms schedules without restarting thecron-systemsession (#88). - Add the
/pr-auditskill, which triages the open-PR queue in one bulk query, separates drafts from ready PRs, and assigns each a single primary state (#76). - Add a Hermes web dashboard opt-in: set
hermes.dashboard: trueinharness.yamlto launch it in theapp-hermes-dashboardtmux session, loopback-only (#376). - Add an
ERR_JOBcron-runtime status line so a synchronous cron job-callback throw is recorded incrons/.cron.loginstead of being silently swallowed (#49). - Add the context fitness-function eval corpus (
evals/) β deterministic probes with a PASS/REGRESSION/SKIPPED exit oracle and aRESULTS.mdscoreboard (#1). - Add the
/evalrunner skill, which runs the probe suite against real state, writes the benchmark, and surfaces greenβred regressions naming the lesson each closes (#1). - Add the
warn-devtcpPreToolUse hook, which warns non-blockingly when a Bash command uses/dev/tcp(#1). - Add the seed probes
next-dev-prod,devtcp-hook, andhealth-check-docker-stats(#1). - Add shared ablation mechanics (
scripts/ablate.sh) and/eval --ablate <file> --probe <id>, reportingLOAD-BEARINGorPRUNABLE(#1). - Add a weekly
eval-weeklycron that runs the probe suite and logs regressions (#1). - Add the
eval-gateprobe pinning that autopilot's Β§6 gate keys on the greenβred delta and runner exit code rather than anyREGRESSIONrow (#22). - Add the autopilot loop: an hourly cron plus
/autopilotskill that selects the next harness-infra item, builds it, and finalizes a ready-for-review PR (#4). - Add the
/drift-checkskill for read-only detection of framework, branch-behind, and cron-staleness drift, with a remediation per finding (#7). - Add a
boot-lintCI job running shellcheck on the boot shell scripts and hadolint on theDockerfile, so a broken boot path can no longer merge with a green CI badge (#26). - Add a heartbeat autopilot-health nudge that kills
cron-autopilot-*tmux sessions frozen at a usage-limit or resume prompt and sweeps orphaned keep-markers (#41). - Add the
clean-restoreprobe pinning autopilot's scoped branch-restore (#45, rescoped by #63). - Add a
Typecheckstep to harness CI runningtsc --noEmitacross both TypeScript packages, with a matching rootpnpm typecheckscript for local-dev parity (#51). - Add
wiki/repo2rlenv.mdon Hugging Face Repo2RLEnv as an RL/evaluation-environment layer alongsideevals/, and regenerate the wiki index (#75). - Harden
/wiki-ingestto regenerate thewiki/README.mdindex when a tracked entry ships, and document the isolated-worktree pattern for concurrent ingests (#75).
/autopilotnow defers the whole build to/ship-spec: it runs/ship-spec --issueand reconciles the outcome, keeping only selection, caps, and cleanup (#140).- Align
/ship-specguidance with the ready-for-review contract: the draft PR stays an observability checkpoint and successful runs continue togh pr ready(#134). - Mirror CI's boot-path lint and eval-probe gates in
release.yml, so tagged releases requirevalidate,boot-lint, andeval-probesto pass before publishing (#111). - Sandbox onboarding banner status markers now prefer emoji (
β/β/β¬) and fall back to the legacy bracket markers outside UTF-8 locales or whenOH_BANNER_STATUS_STYLE=legacyis set. - Cron frontmatter can set
agent: <binary>per job, and Pi cron runs now use an attachable TUI invocation (#116, #118). /autopilotnow defaults to thedelegate-advisorexecutor and leaves itsautopilot-<branch>session alive;AUTOPILOT_EXECUTOR=ralphkeeps the old fallback.- Replace the local Pi plan-mode extension with the upstream
npm:@narumitw/pi-plan-mode@0.4.2package pinned in.pi/settings.json(#107). - Rename cron tmux sessions to the category-prefix convention (
cron-systemandcron-<id>-<MMDD>-<HHMM>), with a guarded migration path from the legacy names (#95). - Cron agent runs now write
AGENT_START,AGENT_FALLBACK, andAGENT_DONElines tocrons/.cron.log, showing which agent started a task and which completed it (#94). - A non-zero cron child exit now appends a bounded (β€200 char) tail of the failing job's log to its
EXIT_<code>line incrons/.cron.log(#73). - Scope autopilot's clean-state check and branch restore to an explicit
OWNED_PATHSsurface, with a dirty owned path skipping asBLOCKED-OWNED-WIP(#63). - Default cron agent execution now falls back from Claude to Codex on usage/session-limit output, and Ralph's fallback order is
claudeβcodexwith requiredSubmitted-by:commit trailers. - Autopilot Β§5 now implements tickets with the resumable Ralph runner, polling
progress.txtforSTATUS: COMPLETEand leavingRALPH-INCOMPLETEruns draft (#55). - Upgrade Docusaurus
3.7.0β3.10.1and add the@mermaid-js/layout-elkpeer, clearing the remainingwebpackandwebpack-dev-serverDependabot alerts (#37). - Replace the placeholder
SECURITY.mdwith a real policy covering private vulnerability reporting, a triage SLA, and the sandbox trust boundary (#33). - Autopilot Β§6's eval gate now keys on the greenβred delta plus the
/evalexit code, so only a new regression keeps the PR draft (#22). - Make
/ci-statusrepo-agnostic by deriving the target repo at runtime, and add a PR-first status path (#20). - A kept per-run cron tmux session now resumes the run's own conversation as an attachable agent (
claude --continue, falling back to a shell) instead of a barebash(#18). - Autopilot v2: issue-queue-first selection, per-run tmux sessions, an
/evalgate before ready, a 10-PR ceiling, and/ship-spec --issue <N>(#14). - Replace the cap of 2 open
autopilotPRs with 6 created per UTC day, and tighten the/harness-auditfallback throttle from 6h to 4h tracked by anAUDIT-RUNmarker (#9). /health-checkgains an in-container RAM-reclaim step using per-containerdocker stats(#1)./retrogains a correction-surface triage tag (harden/proceduralize/eval) routing each promotable lesson to its cheapest closing artifact (#1)./context-auditTier-2 ablation now sources the sharedscripts/ablate.shmechanics, with observable behavior unchanged (#1).- The release pipeline now validates (lint, format check, build, test, root tests) before building or pushing the Docker image or creating the GitHub Release (#24).
- Extend the typecheck gate to
release.yml's validate job for both the workspace packages and the standaloneohCLI, mirroringci-harness.yml(#53). - Warn in
/delegatethat theimplementer/pm/criticsub-agent types are read-only and recommendgeneral-purposefor workers that must write files (#57).
- Fail sandbox boot when the root
pnpm installstep fails, preventing a false-healthy container with missing cron/Pi/Slack dependencies (#136). - Regenerate the wiki index and add a
wiki-readme-indexeval probe sowiki/README.mdcannot silently list missing entries or omit trackedwiki/*.mdpages (#132). - Add a
cron-watchdogtmux supervisor to the devcontainer entrypoint socron-systemrestarts automatically if the cron runtime session dies after boot (#130). - Correct the devcontainer first-boot and interactive shell banners to reference the installed
ohCLI (oh config slack) instead of stale command names (#124). - Validate cron ids before scheduling, skipping unsafe ids, unsafe filename basenames, and id/filename mismatches with
ID_INVALID/ID_MISMATCHliveness lines (#128). - Release the autopilot cron overlap lock on terminal kept Pi sessions, so a retained review pane no longer causes hourly
SKIPPED_OVERLAPstalls (#126). - Remove the stale
workspace/startup.shauto-start hook from the entrypoint and docs, and have/harness-auditcheck for such hooks instead (#120). - Correct the false claim in
context/rules/memory.mdthat dailylog.mdfiles are tracked in git, and add amemory-gitignore-claimprobe guarding the correction (#101). /drift-checkcron-staleness now qualifies eachcrons/*.mdas schedulable before the mtime check, socrons/README.mdis no longer false-flagged (#98).- Scope the weekly
cleanup-taskscron totasks/and isolate its archive commit in a crash-safe worktree, skipping withBLOCKED-TASKS-WIPwhentasks/is dirty (#85). /evalnow writesevals/RESULTS.mdatomically and carries forward untouched rows from a pre-write snapshot, so a filtered run no longer erases them (#83).- Expand autopilot's
OWNED_PATHSguard as a shell array so it word-splits correctly under zsh, with both coupled eval probes updated to assert the array form (#81). scripts/ralph.shnow detectsSTATUS: COMPLETEin the agent's output and self-closes its tmux session instead of spinning toMAX_ITER(#79).- Fix the autopilot one-PR stall: shipped items are checked off after finalize, and dedupe advances to the next candidate instead of ending the run (#9).
- Remove the dangling
.claude/ICP.mdentry from.claude/protected-paths.txt, so critic gates no longer flag a protected path that no longer exists. - De-reference the deleted
.claude/ICP.mdfrom its two live consumers:/ship-speccritic-B now readscontext/USER.md, andcontext/USER.mddrops the dangling citation while keeping the fact. - Add a
pull_requesttrigger and expandedpaths:filter toci-harness.ymlso autopilot PRs touching skills, crons, or context get a real CI status check (#12). /evalnow exits non-zero when any greenβred regression is detected, so CI and autopilot gates receive an unambiguous failure signal (#29).- Fix autopilot loop starvation: with no actionable ticket the run now falls through to
/harness-auditresearch instead of exiting (#41). - Correct stale
docs/wiki/andworkspace/heartbeats/paths in/harness-auditand/skill-lint, and add askill-paths.shguard probe (#43). - Fix the autopilot dirty-tree deadlock: the Β§5/Β§6/Β§7 restores now force a clean restore with an assertion, while a dirty tree at Β§1 still hard-fails (#45).
- Cron definitions now hot-reload their body at fire time, with an unreadable file falling back to the cached body and logging
BODY_RELOAD_ERR(#47). - Cron scheduling is now fault-isolating: a malformed
schedule:is skipped and loggedSCHED_INVALIDinstead of crashing the runtime, and boot logs aBOOTsummary (#67). - Correct stale
apps/andsrc/data/roadmappaths across four skills after theapps/βpackages/rename, and guard the rename tokens inskill-paths.sh(#69). - Extend
boot-lintshellcheck coverage toscripts/*.shalongside.devcontainer/*.shandinstall/*.sh, guarded by aboot-lint-globprobe (#90). - Pin the devcontainer's corepack pnpm to the declared
pnpm@10.33.0and add a CI guard against Dockerfile/package.jsondrift (#114).
- Remove the curated autopilot backlog (
crons/autopilot-backlog.md) and the 4h/harness-auditthrottle, since autopilot is now steered via GitHubautopilotissues (#14).
- Resolve all open critical and high Dependabot alerts in the root
pnpm-lock.yamlviapnpm.overrides(#28, #30). - Resolve moderate and low Dependabot alerts compatible with the Docusaurus 3.7 bundler via
pnpm.overridesand apackages/ohesbuildbump;webpackalerts deferred (#35). - Override
joiβ18.2.1 in the rootpnpm-lock.yamlto resolve GHSA-q7cg-457f-vx79, validated against Docusaurus 3.10 withdocs:build(#39).
- Add an
Eval Probe Regression GateCI job, new eval self-guard probes, and atomic/evalscoreboard writes so greenβred probe regressions block public harness changes (#415). - Load
@tintinweb/pi-goaland@tintinweb/pi-tasksby default in Pi, document their usage, and ignore Pi task runtime state (#415). - Add the public-safe
/pr-auditskill for one-shot bulk PR triage; read-only by default with optional deep review, proof comments, label application, and stale close actions (#415).
- Tighten
/drift-checkcron-staleness detection to compare only schedulable cron files and skip README, disabled, unscheduled, empty, and invalid cron docs (#415). - Correct
context/rules/memory.mdso dailymemory/YYYY-MM-DD/log.mdfiles are documented as local/gitignored journals unless force-added (#415). - Expand boot-path shellcheck coverage to
scripts/*.shandworkspace/*.shwhile preserving the intentional literal~/.openharnessinstaller message (#415).
- Add the
/autopilotskill and hourlycrons/autopilot.mdloop: issue-queue-first selection,/ship-spec --issue, Ralph implementation,/evalgate, PR caps, no auto-merge (#412). - Heartbeat autopilot nudge logic surfaces green/mergeable autopilot PRs, long-lived sessions, and kills only sessions frozen at an unambiguous interactive/usage prompt (#412).
- Autopilot-specific eval probes guard the forced clean branch restore and the corrected eval-gate decision rule (#412).
- Add the
/evalskill andevals/probe corpus: deterministic probes with a 3-state oracle, anevals/RESULTS.mdbenchmark, and non-zero exit only on new regressions (#410). scripts/ablate.shprovides shared swap/restore/trap mechanics for evaluating whether a context file is load-bearing under a deterministic probe (#410)./drift-checkdetects framework drift, branch/append-file drift, and cron-staleness drift without mutating local state; the heartbeat now surfaces its findings when present (#410).- Run
CI: Harnesson pull requests and harness infrastructure paths, add workspace andpackages/ohtypecheck gates, cancel superseded runs, and lint boot paths (#408). release.ymlnow validates lint, format, typecheck, build, package tests, and root script tests before publishing release artifacts (#408).SECURITY.mddocuments supported versions, private vulnerability reporting, automated hardening, and the sandbox trust boundary (#408).- Add Hermes web dashboard opt-in via
hermes.dashboard: trueinharness.yaml, auto-launching it in theapp-hermes-dashboardtmux session, loopback-only on port 9119 (#376).
- Reload cron bodies at fire time, record synchronous job callback failures as
ERR_JOB, and support opt-in tmux-backed cron runs (#408). - Gate the
Docs: build & deployPages steps tomifunedev/openharnessso forks build-validate docs without attempting a Pages deploy (#404). - Make
/releaseresolve the canonical remote (upstream, elseorigin) forREPOand all release pushes, so a release can't land on a private fork (#402). - Point
/ship-specStage 7 at.claude/skills/ship-spec/templates/prompt.mdinstead of the deleted archived task prompt, and repoint two other dead references (#402).
- Dependency manifests and lockfiles are refreshed with Docusaurus/Vitest upgrades and scoped
pnpm.overridesfor current transitive advisory remediation (#408).
- Separate the maintainer's personal state from the public template: empty
MEMORY.mdandIDENTITY.mdlessons, genericizedUSER.md, and anAmerica/Los_Angelesheartbeat (#400). - Change the default sandbox timezone from
America/DenvertoAmerica/Los_Angelesacross image, compose, install script, and cron config, overridable viaharness.yaml(#400).
.gitignorenow ignorestasks/archive/β the priortasks/*/archive/pattern never matched the real path (#400).
- Remove the maintainer's research wiki (11
wiki/*.mdentries pluswiki/raw/snapshots) and task history (tasks/archive/**) from the public template (#400). - Personal agent-fleet docs (
docs/agents/) and their matchingagent/*workspace branches from the public template β moved to the private fork (#400).
- Preinstall
cronin the sandbox base image so scheduled jobs work without a manualapt-get install(#312). - Document "compound engineering" and how the harness embodies it, via
wiki/compound-engineering.md, a public blog post, and pointers indocs/intro.mdanddocs/resources.md(#378). - Add the
/health-checkskill to triage host memory, swap, disk, CPU, and Docker usage, rank reclaim levers by safetyΓyield, and report a RAG verdict naming the binding constraint (#380). - Add
wiki/rubricrefine-agent-reliability.mdon training-free pre-execution refinement for tool-use agent reliability (#391). - Add
wiki/turbovec-turboquant-rag.mdon compressed-vector RAG retrieval (#391). - Add the blog post
blog/2026-06-07-containers-microvms-vms.mdcomparing container, microVM, and full-VM isolation for AI agent execution as a trust Γ tenancy choice (#384). - Add reference docs for the
harness-audit,strategic-proposal, andwiki-ingestskills, each a newreferences/*.mdlinked from itsSKILL.md(#393). - Add the blog post
blog/2026-05-19-four-words-multi-agent.mddefining the Operator / Sandbox / Orchestrator / Harness vocabulary, with a mermaid diagram and a worked example (#320). - Add the
harness.yamlmaster config for non-secret settings, converted byscripts/harness-config.shinto an--env-filethat takes precedence over.devcontainer/.env(#395).
- Move the canonical repo to
mifunedev/openharnessand publish release images toghcr.io/mifunedev/openharness, updating docs, install script, and skills; old URLs redirect (#397). - Exempt
/.hermes/hooks/from the/.hermes/*.gitignorerule so Hermes hook scripts are trackable (#393). - Promote
developmentβmainby fast-forward before cutting the release branch and tag, keepingmainthe authoritative release line and aborting ifmainhas diverged. - Rename the top-level
apps/directory topackages/and update workspace, docs, Dockerfile, CI, and test discovery paths to match. - Require an explicit
--slugin/wiki-ingestfor social/share URLs, long share/activity IDs, and slugs over 60 chars (#373). - Rename and rewrite
/reflectas/retro, a scientific-method session-closing pass with falsifiable hypotheses, verdicts, and confidence across six learning subsystems, keeping the propose-then-confirm gate. - Reduce
.devcontainer/.envto a secrets-only surface (GH_TOKEN,SLACK_APP_TOKEN,SLACK_BOT_TOKEN), migrating all non-secret env vars toharness.yaml(#395).
- Target autopilot caps at the canonical
mifunedev/openharnessrepo via a declaredrepo:and exportedAUTOPILOT_REPO/AUTOPILOT_REMOTE, instead of the checkout's implicit GitHub remote. - Ship
harness.yamlfully commented again so a fresh clone no longer forcesSANDBOX_NAME/TZ, restoring the defaults-stay-authoritative invariant (#398). - Rename three LinkedIn-sourced wiki entries to short semantic slugs, fix their cross-links, and regenerate the stale
wiki/README.mdindex (#373). - Pass
CRONS_DIR,CRON_AGENT_BIN,SLACK_ALLOW_USERS, andSLACK_ALLOW_CHANNELSinto the container via composeenvironment:andharness.yaml; they never reached it before (#395).
- Bump root test tooling and the
@openharness/ohCLI build dependency to clear the remainingesbuild <0.28.1Dependabot alerts (#92).
- Add optional Hermes agent CLI (
INSTALL_HERMES=true) with project-local runtime state and isolated auth, plus documented optional OpenCode and DeepAgents installs (#364). - Add
wiki/sequoia-capital-the-next-1t-company.mdcapturing the Sequoia AI Opportunities thesis that AI-native winners may sell completed services work rather than software tools (#362). - Add
wiki/learn-harness-engineering.mdfor the Walking Labs Learn Harness Engineering course, linked fromdocs/resources.mdanddocs/intro.md(#341). - Add
fast-check^4.8.0 and extend the vitest include glob toapps/**/__tests__/**/*.test.ts, enabling property-based tests across all TypeScript surfaces (#354). - Add the
/imagineskill, a one-shot draft PRD sketch generator that writes a 7-section spec to gitignored.claude/specs/<slug>/spec.mdas input for/ship-spec --plan <path>. - Add a never-throw property test for
parseCronFileinscripts/__tests__/cron-runtime.property.test.ts(#354). - Add a forward-compatibility property test asserting
parseCronFileparses valid frontmatter carrying 1β5 unknown keys (#354). - Add an ordering-stability property test asserting
loadCronsreturns entries in ascending alphabetical order regardless of write order (#354). - Add
.pi/extensions/__tests__/path-guard.property.test.ts, a no-false-positives property test assertingisSensitivePathreturnsfalsefor non-matching paths (#354). - Add
apps/oh/src/__tests__/cli.property.test.tswith determinism and no-throw property tests forisHelpFlagandisVersionFlag(#354). - Document the property-based testing convention in
docs/property-testing.md, including arbitrary patterns, numRuns defaults, a decision tree, and a surface ledger (#354).
- Expose
SENSITIVE_PATHSand a newisSensitivePath(p: string): booleanas named exports from.pi/extensions/path-guard.ts, leaving default-export behavior unchanged (#354). - Export
isHelpFlagandisVersionFlagfromapps/oh/src/cli.tsfor testability (#354). - Let
make shell [container]take an optional running container name viadocker exec, defaulting to$(SANDBOX_NAME); pair withSHELL_USER=<user>for containers without asandboxuser. - Ship Hermes with the Slack messaging extra (
hermes-agent[slack]) by default so the gateway's Slack adapter works without a manual install; requires an image rebuild (#364).
- Point runtime
UV_TOOL_DIR/UV_TOOL_BIN_DIRat sandbox-owned home paths and chown the optional Hermes install directory, so fresh images no longer leak root-owned uv tool paths into thesandboxuser's runtime. - Re-chown
/usr/local/lib/hermes-agentand/opt/uvon every boot so ad-hocuv pip installinto the Hermes venv no longer fails withPermission deniedafter a UID sync (#364). - Store Hermes
auth.jsondirectly inHERMES_HOMEand heal legacy symlinks on boot, fixing cross-device-link (EXDEV) failures on credential saves; requires an image rebuild (#364). - Allow secret-exposure hooks to operate on tracked template env files (
.env.exampleand peers) while real.envfiles still deny; the Codex wrapper inherits the fix (#356).
- Add a
wiki/directory and thecontext/rules/wiki.mdschema implementing the Karpathy LLM Wiki pattern (#351). - Add the
/wiki-ingestskill, which capturesWebFetchsnapshots and authors or updates wiki entries from a URL, path, or--from-draftpromotion (#351). - Add the
/wiki-queryskill, a frontmatter-only grep overwiki/*.mdwith multi-word OR semantics that reads the top 3 entries byupdated:descending (#351). - Add the
/wiki-lintskill, a manual corpus health check with five finding types, atomicwiki/README.mdregeneration, and a--dry-runflag (#351). - Add the
/reflectskill, a whole-session Improve pass that scans the conversation for durable patterns and proposesmemory/MEMORY.md/context/IDENTITY.mdadditions (#337). - Add the
/cavemantoken-compression skill and subcommands, compressing agent prose 65β75% while preserving code and error strings verbatim (#335). - Add the
/context-auditskill, scoring each default-loaded context file with KEEP/TRIM/DEMOTE/CUT verdicts plus a Tier-2 ablation harness measuring behavior degradation (#333). - Add the
/render-htmlskill for rendering an artifact as a self-contained HTML file under gitignoredmemory/<UTC-date>/<slug>.htmlfor one-shot human review (#314). - Add the
/interviewskill, an adaptive pre-work clarifier that batches 2β4 questions throughAskUserQuestion, echoes a scope brief, and skips trivial tasks with an announcement (#316). - Add the blog post
blog/2026-05-19-statusline-context-rot.mdwith a copy-pasteable statusline script surfacing context-window and rate-limit usage percentages (#318).
- Register
/wiki-ingest,/wiki-query, and/wiki-lintin theAGENTS.mdskills table (#351). - Source and version-pin all 15 skills in
.claude/skills/togithub.com/mifunedev/skillsvia.mifune/skills.lock, adding the upstreamedinterviewandrender-html(#327). - Restructure
README.md,docs/installation.md, anddocs/quickstart.mdto surface fork-and-clone and clone-and-own as first-class install paths alongside the upstream one-liner (#331). - Update skill
LICENSEfiles toCopyright (c) 2026 Mifune Dev (mifune.dev)to match the upstream correction. - Re-sync
context-auditto the portable upstream form: dropargument-hint, repin the lock, add the missingLICENSE(mifunedev/skills#6) (#339). - Rename the Slack-bridge tmux session from
agent-pitoclient-slackand restore it on container start when Slack tokens are present, so the bridge survivesdocker compose restartwithout a manual relaunch.
- Install
pi-coding-agentunder the sandbox user's npm prefix and put that bin directory ahead of/usr/bin, sopi updateself-updates without sudo on fresh builds.
- Remove
config.example.jsonand its install-time seeding step, since the base ships zero compose overlays and all readers tolerate a missingconfig.json(#323).
OH_GITHUB_REPOandOH_GITHUB_REFenv vars for fork-friendly installs (#309)./worktreesskill (.claude/skills/worktrees/SKILL.md) β orchestrator skill for managing.worktrees/lifecycle: create, list, remove, clean, stale audit, project clones.
- README and
docs/installation.mdadd a "For forks / self-host" section; canonical upstreamoh.mifune.devURL unchanged (#309). - Make
/releasepush the source branch back to origin right after the CHANGELOG promotion commit, so promotions no longer live only onrelease/*(#297).
- Repair
CHANGELOG.mddrift by restoring the2026.5.14β2026.5.16sections todevelopmentand trimming[Unreleased]to genuinely new entries (#297).
- Add
docs/connecting.md, a runbook for the VS Code Attach + port-forwarding workflow for remote dev servers. (#300). - Agents catalog: add a
docs/agents/section (later renameddocs/harnesses/) with_category_.json, anoverview.mdhub page, and five per-branch playbook pages. (#300).
- Rename
docs/agents/todocs/harnesses/to match the sidebar label and add seven/docs/agents/*β/docs/harnesses/*redirects preserving the old URLs. (#300). - Cross-link
docs/connecting.mdfromintro.md,quickstart.md,harnesses/overview.md,harnesses/t3code.md, andintegrations/slack.md. (#300). - Fix
apps/README.mdscript-name drift:pnpm --filter @openharness/docs devβstart, matching the actual script inapps/docs/package.json. (#300). - Frame the orchestrator-via-VS-Code-attach as the canonical workflow across
docs/quickstart.md,docs/intro.md(with a Mermaid architecture diagram), andharnesses/overview.md. (#302). - Reserve
.worktrees/project/<owner>/<repo>/for standalone repo clones and narrow.worktrees/agent/to agent branches. (#295, #298).
- Raise dark-mode inline
codepill contrast inapps/docs/src/css/custom.css(background0.06β0.12, border0.1β0.22, pure-white text); light mode untouched. (#302).
retro-deterministic-contracteval probe guards that/retrokeeps schema-backed output, self-contained helper scripts, and synchronized.pi/.claudeskill copies (#443).
- Overhaul the
oh config slackwizard UX with masked token input, four numbered steps, per-input validation, and a confirmation summary. (#290).
- Publish container port 1455 on the host loopback (
127.0.0.1:1455:1455) so the Pi harness OAuth callback completes over VS Code Remote SSH port-forwarding (#287).
- Remove every in-tree
.devcontainer/compose overlay exceptdocker-compose.postgres.ymlnow that the entrypoint syncs the sandbox UID/GID to the repo owner (#283). - Remove the orphaned
.pi/onboard-steps/slack.tsand its empty directory; the wizard now lives atapps/oh/src/config/slack.tswith the original port's bugs fixed (#281). - Delete the stale onboarding, lifecycle, connecting, operations, and architecture docs pages, trimming the site to intro, quickstart, installation, and the guides (#279).
- Remove
.pi/overlays/docker-compose.slack.ymland all references to it, since the in-tree Slack Pi extension reads its tokens straight fromprocess.env.
- Migrate
.pi/extensions/slack/{index,tools}.tsoff the deprecated@mariozechner/pi-coding-agentto@earendil-works/pi-coding-agent(#281). - Lead
docs/integrations/slack.mdΒ§ 5 with theoh config slackwizard, which now starts the Slack bridge for you (#281) (ryaneggz/mifune). - Rename the docs sidebar
AgentsβHarnesses, link each harness from quickstart including the new T3 Code, and give every harness page an Authentication section (#281). - Render prose links in Docusaurus
.markdowncontent in terminal green with an underline so they no longer blend into body text (#281). - Add a "Configuration wizards" section to
make helpsurfacingoh config slackandoh --helpas in-sandbox commands (#281). - Document the working Slack env flow: put the tokens in
.devcontainer/.env, then runset -a; source .devcontainer/.env; set +abefore launchingpiin theagent-pitmux session. - Rewrite
docs/integrations/slack.mdfor ID allowlist semantics, the Socket Mode smoke test, and migration off@ryaneggz/mifune(#279).
- Fix the docs landing-page hero quickstart to
cd ~/.openharness && make shell, matching the installer rename (#200, #210). - Fix
pifailing on a fresh sandbox withCannot find module '@slack/socket-mode': the entrypoint now runspnpm install --prefer-offlineon first boot whennode_modules/is missing, opt out withSKIP_PNPM_INSTALL=1. - Add DeepAgents, with a matching icon tile, to the docs landing-page supported-agent copy and agent grid.
- Fix
opencodefailing withEACCESon~/.config/opencodeby extending the entrypoint's parent-chown loop to~/.config(#247). - Fix
opencodefailing withEACCESon~/.local/stateby chowning its parent dirs tosandbox:sandbox(#241, #245).
- Add
oh config slack, an in-sandbox wizard that validates tokens and allowlist IDs, merges.devcontainer/.envatomically, and restarts theagent-pisession (#281). - Add
docs/agents/t3code.mddocumenting the T3 Code browser harness on port 3773, with its pairing-URL auth andnpx t3launch (#281). - Add
build-essentialto the default sandbox image (#263, #271, t3code#2621). - Add
context/rules/recursive-delegation.mdencoding bounded recursive delegation with a/delegaterecursion gate (#269, #270). - Add the Slack integration as a Pi extension at
.pi/extensions/slack/(#261). - Add a project-local Pi single-line footer extension showing cwd/branch, context usage, model and thinking state, extension statuses, token usage, and session name, under a plain
MIFUNEwordmark header. - Add project-local Pi config under
.pi/: OpenAI-defaultsettings.json, banner andpath-guardextensions, a/reviewprompt, and a test suite wired into CI (#255). - Add a project-local Pi plan-mode extension at
.pi/extensions/plan-mode/with/plan,--plan, read-only tool gating, approval prompts, and[DONE:n]progress tracking. - Add tracked
README.mdfiles toapps/,crons/,scripts/,tasks/, and.worktrees/, codified by the new.claude/rules/directory-readme.mdrule. - Add OpenCode as a core sandbox agent: install
opencode-aiin the base image, persist~/.local/share/opencode, add theopencode-hostoverlay, and supportscripts/ralph.sh --harness=opencode. - Add DeepAgents CLI as a first-class sandbox runtime: installed in the image, auth persisted in a
deepagents-authvolume, plusscripts/ralph.sh --harness=deepagents(#237). - Add a
docs/agents/pi.mdstub and a Pi entry in the home-page agent grid, matching Pi's restoration as a default-installed CLI (#233). - Add a top-level
Makefilewrapping the compose invocations withsandbox,shell,destroy,stop,logs,ps,restart, and a self-documentinghelpdefault target.
- Flip the sandbox image name from
<name>-sandboxtosandbox-<name>so harness images group together indocker images(#265). - Move project rules to the canonical
context/rules/, keeping.claude/rulesas a symlink and dropping the inert.codex/rulesand.pi/ruleslinks (#257). - BREAKING: Clone the installer to
~/.openharness/(was~/openharness/);scripts/install.shauto-migrates existing checkouts in place. - BREAKING: Remove the in-repo
.openharness/subdirectory entirely. - BREAKING: Move
composeOverrides[]config from.openharness/config.jsonto a gitignored repo-rootconfig.jsonseeded from trackedconfig.example.json. - BREAKING: Drop
pi-host.ymlfrom the defaultcomposeOverrides; Pi users add it back manually inconfig.json. - Make
/cloudflared-tunnelreconstruct a missing<tunnel-id>.jsonfromcloudflared tunnel tokeninstead of failing (#249). - Collapse the quickstart in
README.mdanddocs/quickstart.mdto one linear flow, demote manual setup to a<details>block, and add a Configuration section for.devcontainer/.env. - Move
install.shtoscripts/install.shper the orchestrator-scripts convention; thehttps://oh.mifune.dev/install.shredirect must be repointed at the new raw URL. - Make
scripts/install.shdetect the hostgh auth token, auto-populate.devcontainer/.envwith timezone and git identity, drop theSANDBOX_PASSWORDprompt, and preserve an existing env file on re-runs. - Use the new
maketargets in theCLAUDE.mdLifecycle section, keeping docker-native commands for deeper inspection. - Rewrite the
.devcontainer/.example.envheader as the single customization surface and flipINSTALL_AGENT_BROWSERtofalseby default. - Consolidate repo-layout documentation into
docs/architecture/container-runtime.md#repo-layout, add.claude/rules/repo-layout-source.mdagainst drift, and remove phantom heartbeat env vars.
- Restore
@mariozechner/pi-coding-agentas a default-installed CLI alongside Claude Code and Codex, with thepi-host.ymloverlay back incomposeOverridesand.piadded to the entrypoint's skip-chown loop. - Add
"type": "module"to the rootpackage.jsonto silence the NodeMODULE_TYPELESS_PACKAGE_JSONwarning on everycron-runtime.tsinvocation. - Add an
## Active itemswatchlist tocrons/heartbeat.mdthat the hourly heartbeat reads to validate deferred follow-ups (#224). - Add the memory concept: long-term
memory/MEMORY.md, dailymemory/YYYY-MM-DD/log.mdlogs, and the write-side protocol incontext/rules/memory.md, auto-loaded at session start.
- Remove
ohCLI references and the multi-agent copy from the marketing landing page, rewriting it around "we provide the sandbox, you choose the harness" (#233). - Hide Gemini from the docs sidebar and sitemap with
unlisted: trueβ the page stays reachable by direct URL β and swap its home-page tile for Pi (#233). - Delete stale files missed in #223:
.devcontainer/tests/cli-binaries.sh,.devcontainer/init-env.sh,.claude/posts/*, andtsconfig.base.json(#228). - Prune four orphaned
.openharness/files left over from the v0.7 convergence and add.openharness/README.md; thecomposeOverridesrole is unchanged (#222). - Remove 0 eligible stale remote branches after critic-gated review β no branch met the >60-day deletion gate (#213).
- Remove five stale or corrupted
.worktrees/agent directories and their worktree registrations, cutting the ignored worktree footprint below 100 MB (#213). - Remove the dead legacy install-side setup, entrypoint, and tmux wrapper scripts now that the Dockerfile wires
.devcontainer/entrypoint.shdirectly (#213). - Remove the empty untracked
packages/web-ui/andpackages/slack/husks, plus the stale Slack workspace and entrypoint references (#213). - Remove the obsolete on-disk SPEC v0.6 artifact so
.claude/specs/exposes only canonical tracked specs (#213). - BREAKING: Deprecate
oh harness addβ packs install viagit cloneplus manualcpfor v1 (#211, #210). - BREAKING: Empty the workspace template of pi-coupled scaffolding, leaving a generic ~22-line agent-runtime stub (#210).
- BREAKING: Triage the orchestrator skills to
/release,/ci-status,/cloudflared-tunnel, and/agent-browser(#210). - BREAKING: Archive the multi-agent comparison narrative β delete the worktree-per-agent draft and move the BYOH post to
blog/archive/witharchived: true(#210). - BREAKING: Remove the
@openharness/sandboxCLI and its package, makingdocker composethe canonical substrate (#210). - BREAKING: Remove the heartbeat daemon and its CLI, tests, env vars, and skill;
scripts/cron-runtime.tsreplaces it (#210). - BREAKING: Drop
@mariozechner/pi-coding-agentas a dependency β the pi CLI and Mom Slack bot move to the separate@ryaneggz/mifuneharness pack (#208).
- Add a root
context/orchestrator identity layer (SOUL.md,IDENTITY.md,TOOLS.md,USER.md) read at session start (#220). - Add
.claude/protected-paths.txtlisting load-bearing paths critics must not propose deleting without an explicit override note (#218). /ship-specv1.1: run the critics before the GitHub issue is opened, so a halted spec no longer leaves a dangling issue behind (#218).- Add the
/ship-specskill composing/prdβ 2 critics β critique gate β/ralphβgh issueβ branch β draft PR in one invocation (#215). - Add a v1 Ideal Customer Profile statement at
.claude/ICP.mdwith the primary persona, top jobs-to-be-done and needs, and an explicit anti-ICP (#210). - Seed the two SPEC-reserved crons:
crons/heartbeat.md(hourly) andcrons/cleanup-tasks.md(Sunday 23:00) (#210). - Start
scripts/cron-runtime.tsin asystem-crontmux session on container boot, replacing the legacyheartbeat-daemonwatchdog block (#210). - Add
scripts/cron-runtime.ts, a croner runtime that schedulescrons/*.mdfrom frontmatter and runs each body throughclaude -p(#210). - Add SPEC v0.7 amendments at
.claude/specs/structure-spec-v0.7.mdresolving seven v0.6 conflicts and adding harness-pack and skill-scope sections (#210). - Add a README "Docker only (no installer)" section with a compose-based deploy path for hosts that have only Docker and git.
- Add per-page OpenGraph and canonical link tags via the
theme.config.tsxhead function (#140). - Add a Worktree-per-agent blog post draft, staged for Wednesday publish (#145).
- Add a blog section at /blog and an About page nav entry (#143).
- Add the BYOH blog post β stop installing agent CLIs on your laptop (#144).
- Add a root
CHANGELOG.mdand document the Keep-a-Changelog workflow in.claude/rules/git.md;/releasenow promotes[Unreleased]to the new version section at tag time. - Generate
sitemap.xmlandrobots.txtduring the docs build vianext-sitemap(#141). - Add a launch runbook consolidating the manual cutover steps (DNS, GitHub settings, OG validation, GSC, promotion).
- Add a Docusaurus v3 docs site at
apps/docs, deployed to oh.mifune.dev (#164).
- Consolidate the cron runtime log onto
crons/.cron.log; the daemon no longer writescrons/cron-runtime.log(#228). - Align the remaining flat-format memory references in tracked docs to the
memory/YYYY-MM-DD/log.mddirectory-per-day form (#210). - BREAKING: Rewrite
CLAUDE.mdfordocker compose-only orchestrator instructions and a four-skill table (#210). - BREAKING: Rewrite the installation, onboarding, lifecycle, and connecting docs without
ohCLI references, deletingdocs/cli/(#210). - BREAKING: Rewrite
README.md,docs/intro.md, anddocs/quickstart.mdfor single-project framing, dropping the side-by-side tagline (#210). - BREAKING: Rewrite
install.shas a docker-compose-only installer, removing the--cli/--with-cli/--install-nodeflags and the Node/nvm/pnpm bootstrap (#210). - Rename the
install.shcurl-pipe target from~/.openharnessto~/openharnessso it no longer collides with the in-repo.openharness/config dir (#200). - Revert to the
sandboxin-container user name (#170, #172, #198). - Consolidate documentation so
/docs/is the single source served by Docusaurus fromapps/docs/, and enable the blog at/blog/(#178). - Auto-detect Node 20+ in the installer and add
--cli/--docker-only/--install-nodeflags;--with-cliis deprecated (#176). - Use the short
https://oh.mifune.dev/install.shURL in the README and installation docs instead of the longraw.githubusercontent.comURL. - Make
/releaseexecute the[Unreleased]β[$VERSION]promotion and haverelease.ymlsource the GitHub Release body from the promoted section, so release notes match the changelog byte-for-byte. - Revert the prior secondary product name; "Open Harness" is the sole brand across README, docs, and onboarding (#157).
- Require an explicit public hostname in the Cloudflare onboarding step, with no default domain (#157).
- Slim the README to ~110 lines and lead with the oh CLI flow (#139).
- Promote the wiki from
workspace/wiki/todocs/wiki/with the same structure, now top-level alongside human-curated docs. - Convert 26 docs pages from Nextra MDX to plain markdown rendered by GitHub.
- Expand
.openharness/config.jsoncomposeOverridesinto-fflags inmake sandboxandscripts/install.shso the default claude/codex/pi host-auth bind-mounts actually apply on a fresh install, and pre-create~/.pi. - Fix the dim Pi icon on the home-page agent grid by restoring the inline
PiIconReact component socurrentColorinverts cleanly between the light and dark themes (#233). - Stop
.claude/hooks/deny-env-dump.shfalse-denyingghheredoc bodies whose prose mentionshistoryorcat .env, and drop the over-broad Tier-2echo|printfASK rule. (commit3ec98fe). - Correct the container runtime docs to show
ENTRYPOINT ["entrypoint.sh"]invoking.devcontainer/entrypoint.shdirectly (#213). - Restore six orchestrator skills removed in error during the v0.7 convergence:
/ralph,/prd,/harness-audit,/skill-lint,/delegate, and/strategic-proposal. - Auto-disable the
*-host.ymloverlays in.openharness/config.jsonwhen the host UID is not 1000, usingjqto filter them out ofcomposeOverrides(#202). - Share host auth (
~/.claude,~/.codex,~/.pi) into the sandbox again by pre-creating the auth dirs before bring-up (#196). - Stop
oh/claude/codexfailing withEACCESon fresh installs by dropping the host overlays from the defaultcomposeOverrides(#194). - Stop
oh sandboxfailing on fresh installs with a Caddyfile bind-mount error by removing the gateway and cloudflared overlays from the defaults (#192). - Lead the
install.shnext-steps with a numbered "source your shell rc" step that detects$SHELL, so users pick upoh/node/pnpmwithout reopening their shell. - Bootstrap
PNPM_HOMEininstall.shbeforepnpm link --globalso the CLI install no longer dies withERR_PNPM_NO_GLOBAL_BIN_DIRon fresh nvm-installed Node. - Stop
install.shsilently exiting when sourcing a pre-existing~/.nvm/nvm.shunderset -euo pipefail, add anERRtrap that names the failing command, and pin pnpm to10.33.0. - Stop the Slack bot dropping oversized replies with
msg_too_longerrors: the main message caps at 2,900 chars and spills into thread replies (#135).
- Remove the legacy
/docs/{plans,wiki,launch-runbook,blog}/andapps/docs/docs/trees, consolidated into/docs/(#178). - Remove the Nextra docs site and the
.github/workflows/docs.ymldeployment; documentation is now plain markdown indocs/, read in the GitHub UI. - Remove the reference Next.js application at
workspace/projects/next-app/, its CI jobs, and the release pre-flight gate referencing it. - Remove the root
package.jsonscriptsdev,docs:dev,docs:build, anddocs:preview.
Release history prior to this file: see git tags and GitHub Releases. Most recent pre-changelog tag: 2026.4.22.