The fork shipped renamed binary/bundle but the product name "Zed" was still
shown everywhere in the UI. Rename the display name to "Joule" (tagline
"Energy-metered agentic coding") while preserving every load-bearing reference.
Display renames (105 .rs files): release_channel display_name, welcome +
onboarding + ai_onboarding, macOS app menu (About/Hide/Quit), window titles,
About panel, settings UI, notifications, update/collab messages, system specs.
Bundle display name (crates/zed/Cargo.toml) -> "Joule" so CFBundleName / the
menu-bar name and the .app are "Joule" (identifier science.transaction.AgentJoule
and the agent-joule binary are unchanged).
Docs (223 .md): product prose Zed -> Joule, fence-aware (code blocks untouched).
Embedded assets (12 JSONC): // comments only.
Legal (4 files): product -> Joule, entity "Zed Industries, Inc." -> "Transaction
Science, Inc.", domain zed.dev -> openie.dev. NOTE: these are structurally Zed's
inherited terms and need a real legal review, not just a rename.
Deliberately PRESERVED (renaming would break the app): font aliases ("Zed Plex
Sans"/".ZedMono" in text_system + assets), HTTP header names (X-Zed-Predict-*),
zed:: action ids, app/bundle identifiers (dev.zed.Zed*, Zed-Editor-* product ids),
zed.dev URLs, ZED_* env vars, crate/package names, "Zed Industries" in non-legal
attribution, and the {zed,Zed} config-dir glob.
Signed + notarized + stapled as Joule.app, installed to /Applications, verified
(Gatekeeper: Notarized Developer ID, FH93XC2VRR). Caveat: test-code string
literals were renamed too, so some `cargo test` assertions may need updating.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
9.6 KiB
Function Breakdown & Codebase Review — agent_joule_panel
Generated 2026-06-14. Per-file inventory of the bolt-on crate. file:line references are against the audited HEAD.
1. Crate overview
agent_joule_panel is the bolt-on that turns this Joule fork into an energy-metered, federated, no-phone-home coding editor. It adds a dock panel (AgentJoulePanel) that drives first-party login-based vendor agents (Claude Code / Gemini / Codex) over ACP — the vendor's own CLI owns its login and tokens; the panel never handles a key — and wraps every request in a five-tier cascade (L0 cache → L1 deterministic → L2 semantic retrieval → L3 on-device GGUF model → L4 remote agent) that closes at the cheapest tier that can, metering host energy and sealing JCR-1 signed receipts at each close. Three entry points: init(cx) (agent_joule_panel.rs:84) starts the control server, registers actions, attaches the on-device FIM provider to every file editor; the AgentJoulePanel view/struct (:177); and the control protocol (control.rs), a CDP-style JSON protocol whose methods land in control_dispatch (:2261).
2. Per-file breakdown
agent_joule_panel.rs (5335 LOC) — panel, cascade, control dispatch
Lifecycle & view: init :84, new :557, load :1080, Render::render :4208 (~500 lines: status, connect buttons, prompt, cascade/grant/methodology/session/hooks summaries, edit-review list, pending-edit Accept/Reject diff, agent step log), impl Panel :4713.
Cascade tiers: submit_prompt :1600 (entry: resolve @-mentions, run cascade), attempt_l1_deterministic :1834 (L1 exact substitution), attempt_l2_then_l3 :1673 (L2 embed+replay), index_for_l2 :1777, attempt_l3_then_l4 :1883 (L3 model gen+apply), send_to_l4 :2462 (L4 ACP forward).
Edit application & review: apply_multi_file_edit :2022, record_multi_edit :2100, stage_pending_edit :2178, apply_staged_now :2204, accept_pending_edit :2231, reject_pending_edit :2246, revert_edit :1002, record_review :986, line_diff :465, diff_stat :502.
Local-agent / index / prediction: run_local_agent :1370 (drives local_agent::run_agent_loop off-thread), index_codebase :1181, predict_here :1269.
Sessions glue: ensure_session_mgr :2656, spawn_session :2699, delegate_session :2735, close_session :2777, verify_session :2799, merge_session :2839, set_active_session :2899, record_active_op :2883, active_session_worktree :2872.
Energy, receipts, ledger: host_energy :3196, energy_uj_now :3213, bracket_energy :2443, append_to_ledger :686, ensure_ledger_loaded :642, seal_op_receipt :738, ledger_receipt :751, verify_entry_seal :772, ensure_l2_loaded :790, append_l2_record :828, record_tier_edit :2542, record_l3_edit :2510, note_close :2602, authorize_tier :2611, life_spent_uj :2637, local_life_exhausted :2643, captured_op :3137, session_receipt :3107.
Control & attestation: control_dispatch :2261 (ping/state/submit/run_agent/accept/reject/open/save/buffer/revert/spawn_session/session_worktree/connect_agent), control_state :2409, attest_unit :548, attest_in_sandbox :1025, attest_applied_edit :3039.
Agent connection: connect_agent :1096, do_connect :1155 (resolve CustomAgentServer, open ACP rooted in the active session worktree).
L3 model (free fns): l3_engine :377, load_l3_model :3393, load_mellum_backend :3416, l3_generate :3540, l3_generate_fim :3560, l3_embed :3583, mellum_generate :3497, l3_sampling :3465, build_coding_op :3237, harness_prompt :3789, parse_edit :3830, parse_substitution :3273, resolve_at_mentions :3701, format_symbol_context :3619, format_codebase_context :4172, session_identity :3994, build_hook_registry :3983.
control.rs (732) — control protocol over Unix socket / TCP / MCP
init_control_server :185, dispatch_foreground :276, serve_conn/process_line :340/:419 (token-aware), Unix/TCP accept loops, list_peers :93 / relay_command :138 / register_self :61 (fleet), run_client :473 / run_client_tcp :506, mcp_tool_specs :533 / handle_tool_call / run_mcp_bridge :673 (stdio MCP server). Types: ControlCommand, ControlInstance (gpui Global).
methodology.rs (993) — spec-driven traceability
MethodologyTracker :78: adopt/adopt_from_file (verify-before-take signed spec), cite_op, record_op, review, set_frame/check_op_in_frame (fail-closed footprint gate), coverage, ship_request/ship_summary/certify_release (four-gate release cert), amortization_line. SpecFile, RunSteering+RunCheckpoint+RunAmendment (mid-run steering, monotonic only-narrowing budget).
sessions.rs (855) — accountable worktree-isolated sessions
GPUI-free. SessionManager :271: open/open_child (attenuated delegation), record_op, mark_verified, merge (refuses unverified), close, delegated_energy_uj. Session (a did:key principal, worktree, branch, grant, status, chain): verify_chain :249. SessionGrant::attenuate :101 (delegate only what you hold). SealedEvent (hash-chained, parent-signed).
local_agent.rs (706) — on-device ReAct tool loop
run_agent_loop :159 (prompt→generate→parse→gate→execute, fix-to-green verify before finish), parse_tool_call, is_allowed_command (allowlist), tools read/grep/list. AgentStep, AgentTrace.
codebase_index.rs (433) — on-device repo-RAG
CodebaseIndex::build :173 (incremental, reuses unchanged vectors), search :69, find_symbol :101 (pure-text def ranking), chunk_file, cosine.
edit_blocks.rs (356) — search/replace edit format
parse_edit_blocks, apply_body/apply_edit/apply_patch (exact → trailing-whitespace-tolerant → SearchNotFound, errors loudly naming the file). EditBlock/Edit/Patch/ApplyError.
hooks.rs (284) — deny-capable lifecycle gates
Hook trait, HookRegistry (with_reference_hooks, gate deny-wins, fire). Reference gates RefuseUnverifiedMerge (PreMerge), JouleCeiling (PreTool budget). LifecyclePoint, HookContext, Denied.
mcp_client.rs (230) — synchronous MCP stdio client
McpClient::connect/list_tools/call_tool, parse_mcp_invocation. Pure std + serde_json.
edit_prediction_local.rs (216) — Cursor-Tab via on-device FIM
LocalFimEditPredictionDelegate (debounced off-thread infill, ghost-text), CurrentCompletion::interpolate.
cascade_gate.rs (207) — JCP gate over L0–L4
CascadeGate::from_env/authorize/l4_granted/grant. Omit l4 ⇒ remote agent structurally unreachable.
sandbox_bridge.rs (202) — federate execution to sandbox-mcp
attested_build (S0–S7 attested build receipt, RATS EAT per step). AttestedStep/AttestedBuild/UnitSpec.
fim_local.rs (182) — pure FIM engine
FimFormat (StarCoder/DeepseekCoder/CodeLlama), fim_prompt, predict_infill, windows_around, clean_completion.
tool_gate.rs (136) — JCP gate over local-agent tools
ToolGate::from_env/authorize per tool call (read_file/grep/list_files/run/edit_file/mcp) against a grant + budget.
3. Key types
AgentJoulePanel:177— central view. Field groups: connection (session,prompt_editor,status,workspace,project); energy (energy_counter,energy_baseline,local_energy_uj); cascade (l0_cache,l2_index,l3_model,tier_closes:[u32;5],codebase_index); gating/accountability (cascade_gate,hooks,methodology,session_key,session_mgr,active_session); ledger (ledger_ops,ledger_energy_uj,ledger_head,ledger_seq,ledger_intact); review (reviews,pending_edit,agent_steps,pending_context,last_intent).L3Engine—Runtime(from-scratch GGUF) |Mellum(in-process safetensors).L3Backend—Runtime(GgufModel,Vocab)|Mellum(Box<MellumModel>,BpeTokenizer,u32).StagedFile{path, old, new, buffer},PendingEdit{files, energy_before, single_path},LedgerEntry{seq, prev, intent, energy_uj, op, seal}.
4. Codebase review
Architecture. A clean spine: GPUI-free pure substrate modules + one GPUI orchestrator. Dependency-injection-by-closure (run_agent_loop, CodebaseIndex::build's embed/progress, predict_infill's generate) keeps heavy/model/IO parts out of the testable cores. The cascade is the central design; JCR-1 sealing + the hash-chained ledger are real with round-trip + tamper tests.
The one debt: agent_joule_panel.rs at 5,335 LOC — ~half the crate, 5× the next file, mixing seven concerns (render, cascade, L3 inference, ledger, energy, control dispatch, ~480 lines of inline tests). Recommended splits (all GPUI-free, move cleanly):
- L3 model loading + generation (
load_l3_model/l3_generate/mellum_generate/l3_sampling/harness_prompt/parse_edit/build_coding_op, ~:3237–:3600) →l3_model.rs. - The persistent ledger (
LedgerEntry,append_to_ledger,ensure_ledger_loaded,seal_op_receipt,verify_entry_seal, ~:329–:790) →ledger.rs(a sibling ofsessions.rs— both hash-chained sealed logs).
Consistency notes: two near-identical MCP stdio clients (mcp_client::McpClient, sandbox_bridge::Mcp); doc comments are unusually rich (occasionally essay-length). Adheres well to the repo's Rust guidelines (let Some(..) else, ?, bounded indexing, .detach()/.log_err() on tasks) — except the load-bearing let _ = discards noted in FINDINGS.md.