The move to vendor/ left four references behind. check-codex-path-deps.sh
hard-failed every build ("Expected both code-rs/ and codex-rs/"), and the
auto-review scope excluded a prefix that now matches nothing — so all 5,624
vendored files were eligible for review context. That exclusion is vendor/
now, which covers whatever else we vendor later.
scripts/install/{install.sh,install.ps1,test_install_sh.py} arrived with the
v0.6.169 merge and nothing in this repo references them. install.sh fetches
releases.openai.com/codex, writes ~/.local/bin/codex, and uninstalls via
@openai/codex — an install path under our name that delivers a different
product.
The installer we actually publish lives in hanzoai/cli and consumes the
canonical <bin>-<os>-<arch>.tar.gz assets release.yml builds. Nothing here
fed it.
Our history is just-every's with author emails rewritten, so the graphs are
disjoint and git finds no merge base. Supplied one by hand: d1f1f51a41, the
just-every commit matching our Oct-2025 fork point (22 files apart). 9618
upstream commits, 7004 files, +1.81M/-159k, 37 conflicts.
Resolution:
- Upstream code where our side was the Oct-2025 prototype of a feature they
have since reimplemented 3-5x larger (agent_runs, browser_sessions,
history_cell/{agent,browser}, the vt100 harness and its snapshots).
- Upstream's config.rs module split (builder/defaults/sources/validation)
kept; zen5-coder and the provider-follows-model rule re-applied on top.
- Ours where the file IS the identity: README, package.json, postinstall,
release notes pipeline, integration-zed.
- Hybrid where upstream improved a file we had branded: updates.rs (their
release-repo migration, our hanzoai/dev), release.yml (their fail-fast npm
auth check, our package name), chatwidget.rs (their turn handling, our
HANZO_USER_KEY hint), exec human output (their 237 lines, our banner).
Superseded and dropped deliberately: our resume_command_name() coder-alias
hack — upstream's derive_resume_command_name() reads the invocation basename
generically, which yields "dev" for us.
LLM.md now records the real topology and the sync point; AGENTS.md and
CLAUDE.md are symlinks to it again. Single parent on purpose: adopting
jecode/main as a second parent would re-import 13,742 commits carrying the
upstream author emails a prior rewrite deliberately removed.
Version 0.2.188 -> 0.2.189.
Co-authored-by: Hanzo Dev <[email protected]>
hanzoai/dev went public defaulting to someone else's cloud. Four things were
wrong, and all four now have a test that fails if they come back.
DEFAULT PROVIDER AND MODEL. built_in_model_providers() gains `hanzo` -- the
Hanzo Cloud at api.hanzo.ai/v1, Responses wire, bearer from HANZO_USER_KEY --
and it is the default. The default model is zen5-coder. This was not cosmetic:
the old default is not in the gateway catalog, so it 400s against our own
cloud. Measured, not assumed:
POST api.hanzo.ai/v1/responses model=gpt-5-codex -> 400 "model is not
available. Use GET /v1/models to list available models"
POST api.hanzo.ai/v1/responses model=zen5-coder -> 200, clean output
Our own CLI already documented the bug from the other side -- dev.rs says
"Name the model too -- codex's built-in default is not in the gateway catalog
and would 400" and passes `-c model=` on every launch to work around it. It
also asserts that on the native gateway NO model_provider override is needed,
which is only true once `hanzo` is the built-in default. It is now.
zen5-coder over enso because dev is a coding agent and because enso returns
system-prompt text on the Responses wire that dev actually speaks; zen5-coder
returns the answer. Model ids were read from GET /v1/models with a bearer, not
guessed. Other providers stay fully configurable -- this is the default, not
the only choice.
THE LOGIN COMMAND. Messages said `code login` / `codex login`. The real command
is `hanzo auth login` (`hanzo login` is not a command -- it is swallowed as an
AI task). It now lives once, as auth::LOGIN_COMMAND, so no message can drift
into naming a command that does not exist. References to this binary's own
subcommand became `dev login`.
A BINARY NAMED dev. HEAD built `code` and `codex` and nothing named `dev`, so a
release cut today would ship no `dev` -- and `hanzo code` launches a bare `dev`
off PATH, so every new install would break. `dev` is now the canonical bin,
declared first; `code` remains as an alias to the same program, never the
reverse. The CLI identifies as `dev` / "Hanzo Dev", not "OpenAI Codex".
OUR NAMESPACES. The pipeline published to @just-every/* on npm and pushed
formulae to just-every/homebrew-tap. Both of ours already exist and are already
populated at v0.6.91 -- @hanzo/dev plus all five @hanzo/dev-<target> packages,
and hanzoai/homebrew-tap's Formula/hanzo-dev.rb, which installs `dev` and
expects assets named dev-<triple>. Nothing here is squatted; this is our own
distribution, reclaimed. Assets are renamed to match the formula.
Two live supply-chain bugs fell out of that, both worse than a naming problem:
postinstall.js (runs on every npm install) and the tui auto-updater fetched
from a third party's releases -- the updater also told our users to
`npm install -g @just-every/code@latest`. Worse, a shadowed `isWSL` const put
the two fast paths in the temporal dead zone, so their catch blocks swallowed
the error and EVERY install fell through to that download: the five published
platform packages were never used, and the third-party fetch was not an edge
case but the only path that ran. Fixed and exercised in a sandbox across all
three paths. codex-cli/.pack/ -- a committed `npm pack` artifact CI
regenerates, and the reason the bad URL had two homes -- is now untracked.
DURABILITY, because upstream-merge.yml merges openai/codex every 30 minutes.
A one-time edit to a default is a suggestion that survives until the next
merge. Two mechanisms:
- .github/merge-policy.json prefer_ours_globs listed only codex-rs/** while
the workspace that SHIPS is code-rs/**, so it protected nothing that
ships. The identity-bearing code-rs files are now listed.
- code-rs/core/tests/hanzo_identity.rs asserts all four properties -- the
provider, a Zen default, a bin named dev, and no third-party publish
target. Upstream has no such file, so a merge cannot conflict with it or
carry the guard away with the thing it guards. Policy can be edited;
a red build cannot be ignored.
The gate is not decorative: it failed on the un-retargeted pipeline
("release.yml still references `@just-every/`") and went green only when the
pipeline was actually fixed.
Verified: cargo build --bin dev clean; hanzo_identity 4/4; code-core lib
332 passed, 1 failed -- git_info::test_collect_git_info_with_remote, which
fails identically on a clean origin/main checkout here because this machine
has a global [email protected]:.insteadof rewrite. Pre-existing and
environmental, not from this change.
$ dev exec "say OK" # fresh profile, no config
Hanzo Dev v0.0.0
model: zen5-coder
provider: hanzo
Co-authored-by: Hanzo Dev <[email protected]>
- Resolve merge conflict in codex-rs/Cargo.lock by adopting upstream version (outside prefer-ours globs).
- Add RUSTUP_HOME export in scripts/upstream-merge/verify.sh to avoid CI HOME permission issues during cargo check.
- Verified via scripts/upstream-merge/verify.sh: build-fast OK, API check OK, static guards OK, branding clean.
- Remove auto-branding worktree + commit and failing guard
- Keep perma-deleted guard; generate VERIFY_branding.log for guidance
- verify.sh: record branding findings as notice, never fail rc; write branding log
Rationale: branding should be a suggestion, not a gate. Code/maintainers can
apply suggested changes explicitly in follow-ups while upstream merge is gated
solely by build + API invariants.
- Prefer release-assets/* when present to compute sha256 for Homebrew formula.\n- Retry curl with backoff if local file missing; print warnings instead of failing.\n- Keep formula URLs pointing to GitHub Releases; add best-effort HEAD checks.\n- Eliminates 404-induced failures right after uploading assets.
- Add to and parse/write in config
- Apply per-server timeout to and initial
- Treat per-server errors as non-fatal; record and skip those servers
- Keep manager creation successful even if some servers time out
- Export so local smoke tool can exercise it
- Add (stdio JSON-RPC) and binary for manual validation
- Update TUI to set by default
This resolves GitHub issue #91 where a slow MCP server caused manager creation to time out and fail entirely.
- Add docs/fork-enhancements.md (initial list; instruct agent to scan repo for more)
- Inject the overview into the merge prompt
- Generalize verify guards to handler↔tool parity by family (browser_*, agent_*, web_fetch), and keep UA/version check
Prevents silent loss of fork features and gives the agent richer context.
- Keep ours for (resume picker not reintroduced)
- Initially took upstream for core, but reverted to ours to maintain API compatibility and pass build
- Adopted upstream elsewhere where non-conflicting
- Guard: keep codex-core re-exports and models alias intact
- Verify script: disable sccache outside GHA to allow local verify
- Fix: remove unused imports in theme selection view (warnings-as-failure policy)
Build: scripts/upstream-merge/verify.sh => build_fast=ok api_check=ok
Use one CARGO_HOME/CARGO_TARGET_DIR across agent and verify. Remove redundant actions/cache steps; rely on Swatinem/rust-cache and sccache GHA backend for incremental builds. verify.sh now respects env and uses KEEP_ENV=1 so builds share caches.
- Prefer ours for TUI/CLI and workflows; theirs for protocol where safe
- Adopt upstream rollout_path in NewConversationResponse; wire through SessionConfiguredEvent
- Add TS derives for protocol types to satisfy upstream TS schema
- Keep core API re-exports and models alias intact
Verification: scripts/upstream-merge/verify.sh passed; ./build-fast.sh clean (no warnings)