lowercase_bash_returns_one_ordered_stream uses printf/redirection
syntax that Windows cmd cannot execute; it ran on Windows CI only
after the pi_output compile gap was fixed and failed deterministically.
Gate it to unix like its neighbor. The approval-test failure on
Windows is being rerun to separate a flake from a real defect.
Source budget follows the added lines (687594).
The exact-surface tests hardcoded tools whose registration is gated on
local backends: image_ocr (tesseract/native OCR) and pandoc_convert
(pandoc binary). CI runners and Linux containers lack those, so the
pinned catalogs drifted and CI has been red for these tests all day.
Expected sets now follow ocr_available()/resolve_pandoc(), and the
image_ocr allowed-tool assert is conditional the same way.
Verified in both directions: macOS host (tesseract + pandoc present)
and rust:1.97.1 Linux container (neither) — all four tests pass.
Also raises the source-structure budget by 4 lines for the rename.
Derive archive mtimes from the pinned source commit in release artifacts, retain reproducible archive bytes and executable modes, and cover metadata plus input validation.
Adopt the six-tool lowercase surface, keep To-do state out of repeated provider prompts, and store Codex-style compaction checkpoints in ordinary history. Preserve provider-specific reasoning continuity, typed image tool results, role capability boundaries, ACP tool turns, and exact regression coverage across the runtime.
`scripts/release/verify-workspace-version.sh` had zero references anywhere:
no workflow under `.github/workflows/`, no `.cnb.yml` job, no runbook
(`docs/RELEASE_RUNBOOK.md`, `docs/RELEASE_CHECKLIST.md`), no other script,
and no entry in the private ops repo. A repo-wide ripgrep across all file
types (hidden files included, `target/` excluded) matched only the file's
own path.
Its job is fully subsumed by two gates that are wired in:
- `require-release-tag-checkout.sh:9-30` refuses to publish unless HEAD is
exactly `refs/tags/v<workspace_version>` on a clean tree, which is the
tag-vs-workspace agreement this script re-derived from `GITHUB_REF`.
- `check-versions.sh` check #1 forbids literal per-crate `version =` values,
so `cargo metadata` versions cannot diverge from the workspace version in
the first place.
Proof: `bash scripts/release/check-versions.sh && bash scripts/release/require-release-tag-checkout.test.sh`
Result: pass — "Version state OK: workspace=0.9.6, npm=0.9.6, lockfile in
sync." then "Release checkout gate OK: clean v0.9.6 at 3815bd705." and
"require-release-tag-checkout tests passed" (exit 0).
Implemented with Claude Code agent assistance.
One command for the provider-neutral invariants the v0.9.6 release repaired:
parent-request compaction pressure, replace-not-stack summaries, the stable
cache prefix, queue-behind-turn manual compaction, durable compaction
receipts, truthful reasoning display, and live shell-wait progress.
Verified: ./scripts/continuity-suite.sh — all three gates PASS.
Implemented with Claude Code agent assistance.
Advance the aggregate owned-Rust ceiling from 684375 to the measured
685062 lines after the post-review fix set (rail/todo visibility, ⌥V
row details, telemetry notice rewording, screencapture stabilization,
fleet read-only web parity, and their regression tests). Module and
large-module ceilings are unchanged; the structure gate passes at the
recorded values.
Move first-run usage disclosure into the native TUI, keep telemetry unarmed until the decision, and order all telemetry writes and delivery against persistent opt-out with fail-closed setup-state handling.
Replace the narrow wide-terminal rail with a responsive full-screen ocean canvas, preserve readable prose measure, and remove per-call padding inside grouped tool activity.
Verified with formatting, clippy, locale/version/budget gates, the 10,120-test TUI library suite, telemetry/config suites, focused UI/PTy coverage, and independent release/UI review. The sandbox-only loopback acceptance rerun remains explicitly environmental.
Agent assistance: Claude and Codex were used for implementation analysis and verification.
Advance the explicit maximum-module and aggregate Rust ceilings to the measured release-candidate tree after the v0.9.6 lane reconciliation. The structure gate remains one-way and passes at the recorded values.
Bump the workspace, every published crate, the npm CLI package and its
codewhaleBinaryVersion, the runtime SDK, and the VS Code extension to 0.9.6 —
the four version sources the release workflow cross-checks before it will
tag.
The changelog entry describes v0.9.6 as what it is: a subtractive release.
The guards that interrupted live work, the per-mode prompt doctrine, and the
deterministic second compaction system are gone; a truncated provider
response can no longer be recorded as a finished answer. Most of these were
found by running v0.9.5 against Terminal-Bench 2.1 beside Pi 0.8.41 on the
same model, effort, endpoint, and task digests, then reading the trials
Codewhale lost — so the entry names those trials rather than describing the
fixes in the abstract.
Mistral AI ships in this release; Xavier Pestel (@xavierpestel-ai) is
credited in the contributors section for #5295.
Three v0.9.5 benchmark tasks could not launch Codewhale at all:
mteb-leaderboard, mteb-retrieve, and pytorch-model-recovery run older ARM64
images, and the aarch64-unknown-linux-gnu artifact built on ubuntu-24.04-arm
requires GLIBC_2.39.
Release and nightly now build aarch64-unknown-linux-musl on the native ARM
runner, alongside the x64 musl build that has shipped since v0.8.65. Both
gain a static check (no ELF INTERP) plus a launch smoke on the matching
native runner, so a dynamically linked or non-starting binary fails the
build rather than the user's install. docs/INSTALL.md drops the arm64 glibc
floor section and describes the v0.9.6 matrix.
Also reconciles the copy the earlier commits invalidated: setup ratification
text and all 15 locales stop attributing execution doctrine to "mode
prompts", docs/MODES.md states Auto-Review's actual deterministic
allow/deny behavior, and the source-structure, dead-code, and
runtime-contract budgets are re-measured — the last locking down 25
decreased ceilings and the new mode-agnostic prompt-stage digests.
Reconcile the aggregate Rust ledger at 685165 lines after the release-gate repairs for session persistence, Scout authority, compact layout, provider-test isolation, and fetched relative links. Package, binary, large-module count, and largest-module ceilings do not grow.
Verified with the source-structure checker and JSON parsing through the checker.
Rebaseline the paused persistence receipt after eliminating duplicate queued history: retained payload drops from 16,924,032 bytes in the broken candidate to roughly 8,528,000 bytes. The ceiling is under 0.5% above the pre-journal schema and includes 0.015% headroom over the largest of repeated clean samples.
Record the final net source delta at 86 lines above the prior review ceiling with no new package, binary, or thousand-line module. Verified with both budget checker suites, repeated clean measurements, JSON validation, and the source-structure gate.
Keep provider-neutral auto selection in the provider-aware TUI and launch workflow lanes from the exact running executable. Repair CNB and installer alias contracts, refresh legacy website-installed TUI bytes during upgrades, and make account pull reject an unimplemented local import truthfully.\n\nVerified with focused CLI/config tests, strict Clippy, workflow contracts, shell syntax checks, and hermetic web installer tests.
Run the ignored persistence backlog receipt test from the TUI library after the integration target move. Pin the exact Cargo command in a hermetic harness test and reject successful zero-test or missing-receipt runs so future test relocations fail clearly.
The npm wrapper exposes codewhale and codew, while v0.9.5 keeps codewhale-tui only as legacy asset filenames for old updater compatibility. Stop npx from resolving a nonexistent codewhale-tui package during the release smoke and make the runbook describe the single compiled runtime accurately.
Verified with the full local npm wrapper smoke against the exact 0.9.5 release binary, node syntax checking, and the website documentation contract.
Record the measured 684,975-line production source boundary for the shared normal/headless Scout authority contract. The same update locks in the existing largest-module improvement from 17,700 to 17,680 lines and removes main.rs from the thousand-line allowlist.
No package, binary, or large-module count is added. Verified with scripts/check-source-structure-budget.py.
Run each ignored receipt test against its exact library path and reject Cargo's successful zero-test result explicitly. Keep the standalone tool-catalog measurement and current verification guidance on the same target, with hermetic command and failure regressions wired into CI.
The repaired measurement exposed a real duplicate AGENTS.md injection from the bounded fragment importer. Keep canonical project-context sources single-owned while still importing additional rule formats through the typed, capped fragment boundary; this restores the checked-in prompt identity without raising the budget.
Verified with the full 55-metric runtime-contract checker, focused core and TUI regressions, both Python harness suites, cargo fmt, and all-target clippy for codewhale-core and codewhale-tui.
Bump every tagged package and internal dependency pin to 0.9.5, refresh Cargo and npm lock records, regenerate the packaged changelog and web facts, and record the user-visible candidate contract. The changelog deliberately remains marked Unreleased candidate until the rebuilt binary is dogfooded and publication is explicitly approved.
Release preparation now updates the runtime SDK and VS Code extension manifests and locks alongside the Rust and npm wrapper versions. The normal version gate checks the same records that the tag workflow requires, and the transactional fixture proves the expanded bump and rollback set.
Build codewhale once, expose the verified bytes as codew across release channels, and retain seven TUI-named release aliases solely so shipped v0.9.4 clients can discover and cross the transition. Current installers and containers expose only codewhale and codew.\n\nVerified with the npm asset suite, exact 34-asset assembly, workflow contract, Homebrew renderer, release-body, dogfood installer, and shell syntax tests.\n\nRefs #5259
- Every session entry carries id + parentId, leafId tracks active position,
in-memory tree projects from journal, context rebuilds root->leaf.
- Tree operations as commands: /tree (render), /branch (move leaf only,
never rewrites history), /fork (new session from any node, interactive
picker per #576 via /fork picker), /resume (picker + foreign-session
import/export container).
- branch_summary and compaction entries are first-class SessionEntryKind
variants (data shape lands now, strategies deferred).
- Spawn-depth tracking on SessionMetadata and Journal; fork increments.
- Foreign-session import/export via SessionImportContainer so /resume can
ingest sessions from other agents.
- SavedSession journal migration: old linear messages -> journal entries
with linked parent chain, leaf = last; new sessions write both journal
and derived messages for compat. Atomic write/fsync/crash-checkpoint
and MAX_SESSIONS=50 preserved.
- Shares entry shape with compaction (same SessionEntry envelope).
Co-depends on #5261 engine split (core journal placeholder already
landed in parallel work on same branch).
- add [lib] to crates/tui exposing codewhale_tui::run(args) -> ExitCode
- thin crates/tui/src/main.rs to call library
- remove codew second binary, add argv0 dispatch in crates/cli/src/main.rs
- replace delegate_to_tui/build_tui_command* /tui_spawn_error/locate_sibling/xAI bail and every Command::new(&tui) site with in-process codewhale_tui::run
- sweep two-process assumptions (path resolution, env-forwarding, session-file handoff) while keeping persistence_actor
- update default-members to single binary and budgets
- fix syntect load_defaults_newlines for 5.3
FEAT-012 adds the shared discovery-shadowing contract (discovery.rs, 235
lines) and the Gherkin acceptance harness (epic_discovery_acceptance.rs,
750 lines) mirroring the accepted FEAT-011 pattern. Aggregate owned Rust
source 673375 -> 674554 (+1179 lines). No new 1000-line modules.
Pay down in v0.9.5 per the existing budget TODO notes.
registry_sync now returns instantly from the local snapshot and
refreshes it in the background: incremental via updated_since, with a
full pagination only when the snapshot is missing or older than a
month, and atomic cache replacement.
- turn_loop: a mid-stream chunk-timeout now counts toward the stream-error
budget (stall with nothing streamed retries transparently; an exhausted
budget fails the turn with the real reason instead of ending Completed
over a frozen block).
- idle engine: a finished background shell task wakes and starts an ordinary
runtime turn even without an active goal; a dead provider route claims the
completion once and reports where the output lives.
- subagent: over-budget final reports spill to a session artifact and the
truncation footer names the retrieve_tool_result ref; write failures
degrade to the honest no-ref footer. Test-only wrappers marked cfg(test).
- waits: agents/wait and agent action=wait default to 30 s and cap at 120 s
(blocked waits deafen the session; settled children report back as
sentinels). Bash action=wait honors timeout_secs/timeout aliases and
block; result metadata reports the real wait_timeout_ms.
- todo_write canonical naming: constructor is new(); work_update/TodoWrite/
todo stay hidden compat aliases; user-visible copy and docs updated.
- behavioral tips: DurableStateWritten fires on successful remember calls;
enum allow removed. voice.rs and work_surface model use let-chains.
- test: Windows path-separator tolerant artifact footer assertion.
- changelog: 0.9.4 additions (Agent Plugins v1.0.0, send_later, /advisor,
quiet mode, automation forms, resume_from, transport resilience,
durability, zh-Hant, update chip, RLM groundwork, stall/wake/truncation/
wait fixes). Dead-code budget re-baselined to 452.
The public repo carried maintainer process that is not contributor-facing
contract: perishable lane state, the release queue, the issue-triage
standard, dated audits and state matrices, per-release completion ledgers,
QA evidence, and design specs. All of it moves to the private
`codewhale-ops` repo, which already holds this class of document.
Moved: docs/ops/CURRENT.md, RELEASE_QUEUE.md, AGENT_READY_ISSUES.md,
MODEL_PROVIDER_AUDIT.md, CONSTITUTIONAL_KERNEL_AUDIT.md, the dated
TUI_DOG_008 state matrix, TUI_METAMORPHOSIS.md,
RECURSIVE_SELF_IMPROVEMENT.md, TTC_DESIGN.md, and the docs/releases/,
docs/evidence/, and docs/superpowers/ trees.
Two were moved and put back. `PREVIEW_REQUEST.md` is cited from
request_manifest.rs, client.rs, and engine/preview.rs, and
`RUNTIME_SIMPLIFICATION_DESIGN.md` is listed in
docs/public-surface-facts.json, which the web vocabulary tests pin. Those
are load-bearing references, not planning notes.
Every surviving link was repointed rather than left dangling: AGENTS.md,
crates/tui/AGENTS.md, CONTRIBUTING.md, docs/ISSUE_TRIAGE.md,
docs/CATALOG_REFRESH.md, docs/AGENT_RUNTIME.md. `npm run check:docs`
passes.
Also re-baselines the source-structure budget for the [Unreleased] work
merged this session (673375 -> 676325 aggregate, 17596 -> 17631 max
module, 175 -> 176 large modules) and declares plugins/agent_plugin.rs as
an allowed thousand-line module. Unrelated to the doc move; the gate simply
had not been re-run since Agent Plugins landed.
673296 -> 673375 (+79 lines), the cost of the test-lane fixes that unblock
the v0.9.4 ship.
The growth is a pinned sandbox backend in the underwater test fixture and
one new test covering the "(unenforced)" rendering the fixture no longer
exercises, plus the rooted-mention and native-separator fixes in
file_mention and their comments. No new packages, binaries, or
thousand-line modules; the max module and large-module count are
unchanged.
The budget's standing note asks that v0.9.4 stop treating aggregate growth
as normal and pay it back in v0.9.5. This bump is a ship blocker, not new
surface, and it is small — but it belongs on that ledger.
- source-structure budget: fold the test-fix commit's 3 executor.rs lines
(673293 -> 673296).
- docs/public-surface-facts.json: sourceCandidate toolCount 67 -> 69 to
match the regenerated web facts (MCP-discovery surface).
- web/lib/release-credits.ts + docs/CONTRIBUTORS.md: add @bistack (#5238)
and extend @SparkofSpike's v0.9.4 entries (#5242/#5240/#5234) — the
changelog/credits/contributors parity test requires exact handle parity.
- core_command_surfaces.feature: the /rlm dispatch copy changed to
'Loading that into a persistent working context...' in a50b6532b
(pre-existing on main, hidden by the cancelled CI); align the step.
Harvested from PR #5238 by @bistack
MCP Registry discovery with Registry-first tool selection: registry_sync
surfaces the eligible local stdio catalog as a complete model-side
candidate set, connect-failure messages classify early-exit/help output
and point recovery at the next Registry candidate, and the bundled
mcp-discovery skill documents the flow.
Conflict resolutions (keep BOTH features where #5077 overlaps):
- engine/tests.rs: import union — the PR's merge_new_runtime_mcp_tools
alongside main's workspace_write_carve_out_applies.
- engine/context.rs: stacked both compaction guards — main's
evidence_available pass-through and the PR's registry_sync intact-set
preservation.
- skills/system.rs: kept main's external tests file; the PR's only new
inline tests were the uninstall pair already dropped with #5077 (main's
dead-code audit removed uninstall_system_skills).
- tools/runtime_mcp.rs: kept both new free functions — main's
reject_shell_metacharacters guard and the PR's connect_failure_message.
- budgets: source-structure raised for the new 1283-line mcp_registry.rs
(175 large modules, 673293 aggregate lines); runtime-contract re-measured
exactly at budget (registry tools sit outside the no-mcp default surface
the fixture profiles).
Harvested from PR #5077 by @Hmbown
Progressive fresh-context disclosure: the constitution ships as a minimal
kernel (Ground truth / User intent and scope / Truthful completion / Put
guarantees in mechanism / Whose word wins) with procedural playbooks
disclosed on demand; project context pack is opt-in
(project_context_pack_enabled) and counted in context reports;
load_skill gains name="list" catalogue discovery.
Conflict resolutions:
- prompts/text.rs: took the PR's kernel rewrite (its mechanism and tests
key on the new section names); main's Playful overlay / legacy-prompt
removals kept.
- prompts.rs: two main-side tests pinned the superseded 'Verify before you
claim' text; updated to pin the kernel's Truthful completion contract.
- tools/skill.rs: PR's name="list" discovery wording + main's current
File action tool naming.
- skills/mod.rs: PR's USAGE trailer + hard prompt-budget assert.
- skills/system.rs: kept main's external tests file; transplanted the PR's
procedural_skill_homes_remain_bundled_and_lazy test. Dropped the PR's two
uninstall tests — main's dead-code audit (849010b03) deliberately removed
uninstall_system_skills.
- context_report.rs: env block lives once in base_source_entries (AlwaysOn,
PR's design); main's native_prompt_block memory path kept; the PR's
moraine_fallback test dropped (field removed from main); both project-pack
tests kept.
- tui/ui.rs: PR's apply_workspace_runtime_state line transplanted into
ui/apply.rs (function moved by the ui split).
- budgets: runtime-contract regenerated from measurement (28 metrics
shrank ~40%, 5 grew, 17 identity changes — all from the feature); source
aggregate folded +76 lines to 671740.
Harvested from PR #5240 by @SparkofSpike
shell tool: surface real wait elapsed time in tool content instead of the
requested timeout.
Conflict resolution: kept main's one-way source-structure ratchet values
(174 large modules, 17596 max module lines) and folded the merged lanes'
+389 production lines into the aggregate ceiling (671275 -> 671664,
measured via scripts/check-source-structure-budget.py).
The v0.9.4 must-fix items (composer cursor/wrap unification, Windows
start_turn Box::pin, the #5032 dangling xAI OAuth repair + its test, the
platform-aware /status safety-policy test, the 0.9.4 checkpoint bump) grew
owned Rust by +201 lines (668406 -> 668607), tripping the one-way aggregate
ratchet. No new 1000-line modules; growth is in existing files. Re-baseline
the ceiling and record why; pay the aggregate back down in v0.9.5.
Third and last conflict from the #5123 fail-closed rule. The release QA
contract `release_four_read_only_fleet_roles_launch_with_canonical_prompts`
launches worker, scout, reviewer, and verifier — it calls that set "the
four canonical read-only Fleet roles" — and the worker stopped launching
at all (`worker did not launch once: 0 != 1`).
Worker is the unnamed default role; it renders as `general` and takes its
capability from `write_authority`, not from its name, so a read-only
worker is an ordinary general-purpose child. Builder is the role that
actually claims write capability, and it is the one the #5123 transcript
shows self-BLOCKING — the worker in that same transcript ran fine.
So the check is now exactly: caller wrote `type`, that type resolves to
Builder (either spelling), and authority is read_only. Everything else —
`type=worker` + read_only, any `role` + read_only — stays legal.
Verified: release_four_read_only_fleet_roles_launch_with_canonical_prompts
passes; builder_plus_read_only_authority_fails_closed covers both the
`builder` and `implementer` spellings; new
read_only_worker_is_an_ordinary_general_child pins the canonical case;
the workflow, roster-role, and narrowing contracts still pass (8 total).
cargo fmt clean; structure ceiling folded to 668406.
The earlier re-baseline was measured before the role/type spawn fix, its
regression tests, and the env-lock line landed, so the ratchet caught
this lane's own growth: 668365 -> 668400.
Verified: scripts/check-source-structure-budget.py -> PASS.
The one-way ownership ratchet failed the release train on the v0.9.4
Fleet work. Reviewed and re-baselined:
- aggregate owned Rust 662389 -> 668365
- three new 1000-line modules admitted: fleet/store.rs (1114, the named
Fleet store v2), tui/transcript.rs (1062, the release-quality
transcript pass), views/fleet_detail.rs (1056, the secondary
named-Fleet editor behind /fleet fleets)
Also tightened rather than left slack: seven modules have since split
below the threshold (cli/cloud.rs, client/responses.rs,
session_control_acceptance.rs, skills/system.rs, tui/footer_ui.rs,
widgets/footer.rs, widgets/header.rs) and are dropped from the
allowlist, so the count lands at 168 and the largest module at 19087.
All three new modules are recorded as v0.9.5 split candidates.
Verified: scripts/check-source-structure-budget.py -> PASS with no
"can tighten" remainder.