Omega deltas from Zed
Omega is a fork of Zed. Every place Omega deliberately behaves differently from upstream is recorded here, and every entry is mechanically checked.
The reason this file exists: a fork accumulates silent divergence. Someone changes a default, a rebase quietly reverts it, and nobody notices until an owner sees the upstream behaviour again in a release candidate. A comment in the code is not enough, because a merge can drop the comment and the value together.
Rules
- Every delta has an ID (
OMEGA-DELTA-NNNN), and the ID appears in the code it governs, so a reader who finds the code finds the reason. - Every delta has a programmatic check in
crates/omega_deltas/, so a rebase that reverts it fails the test suite instead of shipping. - Every delta has its own test. A delta whose check cannot fail is not a check. Each test asserts the Omega value and names the upstream value it replaces, so the diff stays legible.
- A delta is a policy record, not a changelog. Record why the owner wanted it, not what the commit did.
- Removing a delta is a policy change, and needs the same care as adding one: delete the entry, the check, and the test together.
- An inherited test that contradicts a live delta loses. A rebase can bring back an upstream test asserting the pre-Omega value, which makes the tree self-contradictory: two tests, one value, neither able to pass. The delta is the policy record, so update the inherited assertion to the Omega value and name the delta ID in a comment beside it. Do not delete the test to reach green — establish what else it covered and keep that coverage under a fixture that does not depend on the shipped default.
- An ID names exactly one entry, and IDs are never reused.
OMEGA-DELTA-0012andOMEGA-DELTA-0013were originally landed as second uses of0010and0011by two lanes allocating numbers at the same time, which made four entries uncitable. They were renumbered on 2026-07-25.delta_ids_are_uniquenow fails on a repeat, in both the registry headings andENFORCED_DELTAS, so the collision cannot recur silently.
Run the checks with:
cargo test -p omega_deltas
Registry
OMEGA-DELTA-0001 — No Restricted Mode, no trust prompt
- Upstream Zed:
session.trust_all_worktreesdefaults tofalse. Opening an unrecognized project shows an "Unrecognized Project" modal offering "Stay in Restricted Mode" or "Trust and Continue". Restricted Mode blocks project settings, language servers, and MCP server integrations. - Omega:
session.trust_all_worktreesdefaults totrue. Nothing is restricted, so the modal never auto-shows. - Why: owner direction, 2026-07-25, on seeing the prompt in
0.2.0-rc3: "I HATE THAT. I NEVER WANT TO SEE THAT AGAIN. NO RESTRICTED SHIT." Omega is an owner-operated editor opened on the owner's own repositories. The prompt interrupts every new project, and declining it silently disables language servers and project settings — which reads as the editor being broken rather than as a security posture. - Also: the modal body told the user to "Review .zed/settings.json", an unclassified Zed identifier on a visible product surface, which omega#16 forbids independently of the owner's preference.
- Enforced by:
crates/omega_deltas/src/omega_deltas.rs,trust_all_worktrees_defaults_to_true. - Correction, 2026-07-25 (adversarial review). An earlier version of this
entry claimed the
ToggleWorktreeSecurityaction still opens the modal on demand. That was false.can_trust(crates/project/src/trusted_worktrees.rs:469) returns early whentrust_all_worktreesis set, before populating therestrictedmap, sohas_restricted_worktreesis permanently false andshow_worktree_trust_security_modal(crates/workspace/src/workspace.rs:8541) returns without opening anything. The action is a silent no-op. This delta therefore does remove the ability to inspect trust — invisibly, rather than by deleting the code. - The Zed identifier is still in the tree. The modal body's
"Review .zed/settings.json" (
crates/workspace/src/security_modal.rs:196) was made unreachable, not removed. Tracked separately; unreachable code that a rebase can revive is not a fix. - Remote peers cannot reintroduce it.
handle_restrict_worktrees(crates/project/src/project.rs) used to callrestrict()unconditionally, so a remote server running upstream Zed could push Restricted Mode onto this machine regardless of the local default. It now returns early whentrust_all_worktreesis set.
OMEGA-DELTA-0002 — Agents do not ask before every tool action
- Upstream Zed:
agent.tool_permissions.defaultis"confirm". Every agent tool action prompts before running. - Omega: defaults to
"allow". - Why: Omega's purpose is unattended agent work. With nobody watching, a confirmation prompt is not a safeguard — it is a hang, and the run stalls until a human returns. Owner direction, 2026-07-25: Omega is "YOLO mode throughout, aka 'do what the user tells you'".
- The line is still drawable.
always_confirmandalways_denypatterns keep working and are the supported way to gate a specific operation, such asgit reset --hard, force pushes, or reads of.envand key material. Omega ships none by default because the owner asked for none. Anyone who wants one adds a pattern rather than reverting this default. - Known tradeoff, stated plainly: an agent can now run a destructive command without asking. That is the requested behaviour, not an oversight.
- Enforced by:
agent_tool_permissions_default_to_allow. - Inherited test reconciled, 2026-07-25 (omega#73).
agent_settings::test_default_json_tool_permissions_parsereads the shippeddefault.jsonand still asserted the upstreamConfirm, so the tree contained two tests asserting opposite things about one value and neither could pass. That test arrived with an upstream rebase and was never reconciled with this delta. It now assertsAllowand cites this ID, and the"confirm"parse coverage it used to provide incidentally was moved to an explicit fixture intest_tool_permissions_explicit_global_defaultrather than deleted — the parser must still understand"confirm", because that is how an operator draws the line back.
OMEGA-DELTA-0003 — Quitting is never confirmed
- Upstream Zed: ships a confirm-on-quit path.
- Omega:
confirm_quitdefaults tofalse. - Why: quitting is deliberate and recoverable; unsaved buffers are handled
by
restore_unsaved_buffers, not by a modal. - Note: this value already matched. The delta exists to lock it, so a rebase cannot quietly reintroduce the prompt.
- Enforced by:
quitting_is_never_confirmed.
OMEGA-DELTA-0004 — Telemetry stays off
- Upstream Zed: ships telemetry defaults that may change between releases.
- Omega:
telemetry.diagnosticsandtelemetry.metricsboth default tofalse. - Why: privacy posture, and Omega has no telemetry endpoint of its own. A posture that depends on nobody changing an upstream default is not a posture.
- Note: these values already matched, and are locked for the same reason as
OMEGA-DELTA-0003. - Enforced by:
telemetry_stays_off.
OMEGA-DELTA-0005 — No hosted-plan or trial surfaces
- Upstream Zed: ships subscription plan definitions (Free / Pro / Business /
VIP / Student), a trial-ended upsell that covers the agent panel and calls
block_mouse_except_scroll, and a banner explaining that GitHub accounts under 30 days old cannot start a Pro trial. - Omega: these files are deleted —
crates/ai_onboarding/src/plan_definitions.rs,crates/ai_onboarding/src/young_account_banner.rs, andcrates/agent_ui/src/ui/end_trial_upsell.rs. - Why: Omega does not sell a hosted AI service, so these advertise a product that does not exist here, and they present Zed as the vendor, which omega#16 forbids. The upsell also blocked operator input to show an advertisement.
- Enforced by:
removed_surfaces_stay_removed.
OMEGA-DELTA-0006 — Nothing nags from ambient state
- Upstream Zed: suggests installing an extension when a file's language is
unrecognised, suggests reopening in a dev container based on repository
contents, and asks to move the application into
/Applicationsat startup — the last with a "Don't ask me again" button, which is an admission that it is a nag. - Omega: all three are deleted, along with the subscriptions that drove them.
- Why: none responds to anything the operator did. They interrupt because the editor noticed something. An interruption has to be earned by a user action or by preventing irreversible loss.
- Enforced by:
removed_surfaces_stay_removed.
OMEGA-DELTA-0007 — Terminating a debug session does not ask
- Upstream Zed: prompts "This Debug Session is still running. Are you sure you want to terminate it?".
- Omega: terminates immediately.
- Why: terminating a debug session loses the session and nothing else. The operator asked for it.
- Not covered: the restart confirmation at
crates/workspace/src/workspace.rsis left in place. It is gated onconfirm_quit, whichOMEGA-DELTA-0003already locks tofalse, so it is unreachable in Omega. Deleting it would mean surgery on the shutdown path for no behavioural change. - Enforced by:
debug_terminate_never_prompts.
OMEGA-DELTA-0008 — No Zed subscription or hosted-plan copy
- Upstream Zed:
zed_ai_descriptionincrates/language_models/src/provider/cloud.rsrenders a subscription pitch — Pro, Student, Business, VIP, and "Subscribe for access to Zed's hosted models. Start with a 14 day free trial." - Omega: replaced with neutral copy about a configured provider.
- Why: it advertised a product Omega does not sell, named Zed as the vendor, and told the operator to buy something they cannot buy. omega#16 forbids presenting Zed as the product.
- How it was found: scanning the installed rc4 binary, not the source tree. The earlier source-level passes missed it because it lives in a different function from the plan definitions that were deleted. Binary verification is the only reason this is not still shipping.
- Enforced by:
no_zed_product_copy_survives_anywhere.
OMEGA-DELTA-0009 — The Restricted Mode UI is gone, not dormant
- Upstream Zed: a security modal, a title-bar "Restricted Mode" badge, a settings banner, and the trust-modal plumbing behind them.
- Omega:
crates/workspace/src/security_modal.rsis deleted, along withshow_worktree_trust_security_modal, the auto-show on project open, theToggleWorktreeSecurityhandler, the title-bar badge, the settings banner, the profile-selector and language-server Restricted Mode affordances, the default Restricted Mode key bindings, and the component-gallery sample that carried "Review .zed/settings.json". - Why:
OMEGA-DELTA-0001stopped the modal appearing but left it compiled in, which an adversarial review flagged and a binary scan confirmed — the.zed/settings.jsonidentifier was still shipping in0.2.0-rc4. Unreachable code that a rebase can revive is not a removal. - Enforced by:
removed_surfaces_stay_removed,no_zed_product_copy_survives_anywhere, andrestricted_mode_ui_and_shortcuts_are_absent.
OMEGA-DELTA-0010 — The title-bar identity entry stays local
- Upstream Zed: the title-bar Sign In button starts the hosted-account browser flow.
- Omega: the title bar presents Omega Identity and opens the local identity-first onboarding journey.
- Why: Omega's inherited service endpoint is intentionally non-routable. A visible control must not send the owner to a browser error page, and local Omega identity is the product's actual account boundary.
- Enforced by:
title_bar_identity_entry_opens_onboarding.
OMEGA-DELTA-0011 — AI onboarding configures providers, not a hosted plan
- Upstream Zed: agent and edit-prediction onboarding inspect the Zed account plan, offer hosted sign-in, and promote hosted AI tiers.
- Omega: agent onboarding lists directly configured providers and opens Agent Settings for provider credentials. Edit-prediction onboarding only configures its retained GitHub Copilot provider.
- Why: provider setup is a local Omega capability. Zed account status, trials, hosted-plan callbacks, and hosted sign-in are not.
- Enforced by:
ai_onboarding_is_provider_only.
OMEGA-DELTA-0012 — Zed collab is retired
- Renumbered 2026-07-25. This entry landed as a second
OMEGA-DELTA-0010. Cite0012. - Upstream Zed: ships a collaboration product — a collab panel with a
nested channel tree, contacts, calls, channel notes, and a
collabserver crate behind it. - Omega:
crates/collab_uiandcrates/collabare deleted, along with the panel registration, theCollab Panelmenu item, theToggleFocusaction, and theopen_channel_notesCLI path. - Why: owner direction, 2026-07-25. Collab is not an Omega product surface. Omega never ran the collab server, and nothing else in the workspace depended on it. The Buzz parity ledger states the replacement direction explicitly: workrooms are "native GPUI panes over the Nostr workroom log" and people and agents are "signed Nostr identity, profile, membership, and presence events". Carrying Zed's channel and contact model forward would fight that.
- Harvested first. The owner asked for retirement unless something was
worth keeping for Buzz parity, and the GPUI panel shapes were: the nested
channel tree with expand/collapse and drag reparenting, per-row context
menus, unread and mention indicators, the fuzzy roster picker, and the
membership modal. Those map onto the Workrooms and People-and-agents parity
rows and are recorded in
docs/buzz/2026-07-25-collab-ui-harvest-before-retirement.mdin the openagents repository, with recovery instructions. The code is gone; the map is not. - This also removes the three collab confirmation prompts on omega#54's list. They die with the feature rather than separately, which is what that entry asked for.
- Enforced by:
removed_surfaces_stay_removed.
OMEGA-DELTA-0013 — The agent is on by default
- Renumbered 2026-07-25. This entry landed as a second
OMEGA-DELTA-0011. Cite0013. The comment atassets/settings/default.json:1063still reads "See OMEGA-DELTA-0011" and now points at the AI-onboarding entry instead of this one. That file is owned by another lane this session, so the correction is deferred rather than made here; it is a stale citation, not a behaviour change. - Upstream Zed: ships the agent enabled.
- Omega, before this:
agent.enabledandagent.buttonwere bothfalseinassets/settings/default.json, turned off by commit9e585569cb("Isolate Omega from Zed production services"). - Omega now: both
true. - Why the original change went too far. The isolation sweep was right about
the hosted-model path —
language_models_cloudis still gated behindOMEGA_ALLOW_ZED_SERVICES, and it stays gated. But it disabled the agent, which is not a Zed service. The runtime (crates/agent), the thread abstraction (crates/acp_thread), the tools, and eighteen local and direct providers are Omega's own and reach no Zed host. - What the owner saw. With
enabled: false,agent_uialso removes theagent,agents, andassistantnamespaces from the command palette (crates/agent_ui/src/agent_ui.rs:836-840), and the panel reportsenabled() == false(agent_panel.rs:5035). So the feature was not merely off — it was unreachable, and the Settings UI exposes onlyagent.button, neveragent.enabled. There was no in-product way to turn it on. - Nothing structural was removed, which is why this is two booleans: the
panel is constructed, the actions are registered, and roughly thirty
agent::*keybindings already existed and were simply unreachable. cmd-shift-a/ctrl-shift-anow opens a new agent thread globally.agent::NewThreadpreviously existed only in panel-scoped contexts bound tocmd-n, so it could not start a thread unless the panel already had focus.- The default model is
google/gemini-3.6-flash. An earlier revision of this entry recordedollama/llama3.1and said the agent needed a local Ollama to work out of the box. That stopped being true when the owner set the Google default, and this text is corrected rather than left to mislead. The agent now needs a Google API key, not a local model server. - Why the isolation test alone was not enough. The service-isolation test
asserts only that the default provider is
google(crates/app_identity/src/service_isolation.rs), because what it protects is that the default never points at a Zed service. That is the right scope for that test, but it leaves the model string unpinned: a rebase could changegemini-3.6-flashto any other Google model and every check would stay green. - Enforced by:
the_agent_ships_enabled,the_default_model_is_pinned, andthe_new_thread_chord_is_window_global, which asserts the chord is bound window-globally toagent::NewThreadin all three default keymaps and that every narrower binding of it is one of the deliberately admitted surfaces — the toolchain and recent-projects pickers, and (on Linux and Windows, where the chord isctrl-shift-a) a terminal's select-all. omega#76 asked for the shadowed lower-priority bindings to be resolved deliberately; this is that resolution written down, so a new shadow fails rather than quietly making the chord focus-dependent again.
OMEGA-DELTA-0014 — A protected recovery offers replacement, not protection
- Upstream Zed: has no equivalent. The onboarding Identity section is an Omega surface, so what this entry locks is a divergence from Omega's own earlier behaviour. It is registered here because a refactor of that branch reverts it as silently as a rebase would.
- Omega, before this: the
CustodyState::Readybranch ofcrates/onboarding/src/identity_section.rsswitched the description and the colour onRecoveryProtectionState, then emittedactions: vec![IdentityAction::Protect]unconditionally. A protected identity therefore read "Recovery protected" in green with a Protect recovery button directly beneath it. - Omega now: the branch selects the action from the same state it already
used for the copy —
Protectwhen protection is needed,ReplaceRecovery("Replace recovery file") when it is not. - Why: owner report, omega#68, 2026-07-25. A control whose label denies the status line above it reads as "this did not work", which for a custody surface is a confidence defect rather than a cosmetic one.
- Rotation was kept deliberately. Hiding the control when protected was the simpler option and was not taken. Replacing a recovery file is a real journey, so the control stays reachable and is relabelled — option 2 on the issue. Dropping it silently is exactly what that issue's falsifier forbids.
- What the check catches: a
Readybranch that emits a constant action again. It asserts theReplaceRecoveryvariant and its label still exist, that the branch is state-conditional rather than a literalactions: vec![IdentityAction::Protect],, and that the crate-local regression test keeps itsassert_ne!on the two states — so deleting the behavioural test is caught here too. - Enforced by:
crates/omega_deltas/src/omega_deltas.rs,protected_recovery_offers_a_different_action.
OMEGA-DELTA-0015 — cmd-shift-s opens the Sarah workroom
Upstream Zed: binds the chord to
workspace::SaveAsin all three default keymaps, and has no workroom.Omega: all three default keymaps bind
workroom::OpenPanel—cmd-shift-son macOS,ctrl-shift-son Linux and Windows — in theWorkspacecontext section, once each.Why: owner direction, 2026-07-25 (omega#69). The action already existed and both focused the panel and marked the room read (OMEGA-SW-06), but no keymap named it, so the workroom was reachable only through the command palette. Opening the workroom must not depend on whether an editor, a terminal, or a panel happens to hold focus — a focus-dependent binding is that issue's stated falsifier.
Workspace, not a context-free section — deliberately, and not what the issue's text asked for. omega#69 said "the top-level section with no context predicate". The binding landed in theWorkspacesection instead, which is the root context of the window tree: it matches from an editor, a terminal, or any panel, so the Exit holds. It is also where every other window-global Omega chord lives —workspace::Save,workspace::NewWindow, and theagent::NewThreadbinding fromOMEGA-DELTA-0013. A truly context-free section is where themenu::bindings live and would have made this chord fire inside menus and pickers too. The check therefore accepts either no context or a context inWINDOW_GLOBAL_KEYMAP_CONTEXTS, and rejects anything narrower.The Save As trade, stated plainly. A keystroke was taken, not shadowed. This is what omega#69 asked to confirm before landing. The chord did not go to the workroom because it was free — it was
workspace::SaveAsin all three default keymaps and was overwritten (default-macos.json:708,default-linux.json:651,default-windows.json:645at7b347cb9a4^). After this delta:- macOS and Windows have no default Save As keystroke at all.
- Linux keeps only
shift-save, the hardwaresavemedia key, which most keyboards do not have. - Emacs-keymap users are unaffected:
ctrl-x ctrl-wstill saves as, in bothmacos/emacs.jsonandlinux/emacs.json. - No other base keymap — VS Code, JetBrains, Sublime, Atom, Cursor, TextMate — binds Save As at all, so none of them restores it.
The mitigation is the File menu, not the palette:
Save As…remains atcrates/zed/src/zed/app_menus.rs:129, so the cost is discoverability rather than capability. The check asserts that menu item still exists, because if a later cleanup drops it, Save As becomes reachable only by knowing its command name — and this entry would then be recording a mitigation that no longer exists.Two narrower bindings overlap the chord and keep precedence, so they are not affected either way:
specific-overrides-macos.jsonandspecific-overrides.jsonbind it topicker::ToggleMultiSelectin contextPicker > Editor, andmacos/textmate.jsonbindsctrl-shift-stosearch::SelectPreviousMatchinBufferSearchBar— a different chord from the macOScmd-shift-s.Why the check is stronger than asserting the string is present. In
0.2.0-rc6Omega hard-panicked before any window opened because 27 bindings named actions whose crates had been deleted: the built-in keymap is loaded and unwrapped at startup, andcargo check --workspacepasses regardless because keymaps are runtime assets. So the check parses each keymap, requires exactly one binding of the chord — a second, narrower one would shadow the global one depending on focus — requires its context to be window-global, and resolves the action name back to a liveactions!declaration incrates/zed_actions/src/lib.rs. Renaming or deleting the action fails here rather than at the owner's next launch.Enforced by:
required_keymap_bindings_resolve.
OMEGA-DELTA-0016 — Aiur is dark-only
- Upstream Zed: ships no Aiur, and its own defaults (
One Dark/One Light) both name themes it ships. - Omega, before this:
assets/themes/aiur/aiur.jsondeclared two themes in one family —Aiur DarkandAiur Light— andDEFAULT_LIGHT_THEMEpointed atAiur Light. - Omega now: the family declares exactly one theme, named
Aiur, appearancedark.DEFAULT_DARK_THEMEisAiurin bothcrates/theme/src/theme.rsandcrates/settings_content/src/theme.rs.DEFAULT_LIGHT_THEMEisAyu Light, whichassets/themes/ayu/ayu.jsonships. - Why: owner direction, 2026-07-25 (omega#70): "aiur light looks like shit and is not what i envisioned. its a dark mode theme only." A family carrying a variant the owner disowns is worse than a family with no variant, because the appearance switch can select it without being asked.
- The Aiur card stays selectable in Light appearance, resolving to
Aiur:LIGHT_THEMESandDARK_THEMESincrates/onboarding/src/basics_page.rsboth listAiurfirst. Choosing the Aiur family gives Aiur in either appearance rather than substituting a light theme the owner did not pick. Hiding the card in Light mode was the alternative and was not taken, because a family vanishing from a three-card selector reads as a bug. - The check answers the issue's falsifier directly. That falsifier is Light
appearance resolving to a missing theme because a default still names one
that no longer exists. So the check does not merely assert the constant's
text: it collects every theme name actually declared under
assets/themes/and asserts both defaults are in that set, and that the two independentDEFAULT_DARK_THEMEconstants still agree. Deleting a variant without repointing a default fails here rather than at first light-mode launch. - Enforced by:
aiur_is_a_single_dark_theme,default_themes_exist_in_shipped_assets, andthe_shipped_theme_defaults_are_the_omega_themes. - Amended 2026-07-25 (omega#73): the check was reading the fallback, not the
value that ships.
default_themes_exist_in_shipped_assetsreadsDEFAULT_LIGHT_THEMEandDEFAULT_DARK_THEME, whichtheme_settingsconsults only when no settings layer names a theme.assets/settings/default.jsonis the base settings layer and always names one, so"light": "Ayu Light"/"dark": "Aiur"there are what actually select the theme — and they were unchecked. A rebase restoring"One Light"/"One Dark"in that file would have shipped One Dark with every check green, because One Dark is still a shipped theme and both constants would still have said Aiur. The new check asserts the shipped values name shipped themes and agree with the constants, so a half-revert of either mechanism fails. - The same values live in a second shipped file, and nothing read that one
either.
assets/settings/initial_user_settings.jsonis the template copied into a new user's own settings file on first start, and it also names"Ayu Light"/"Aiur"(3493676d71). A revert there is the more durable of the two: it lands in the user layer, which overrides the base layer, so correctingdefault.jsonafterwards would not undo it. Both files are now read by the same check. - Inherited test reconciled, 2026-07-25 (omega#73).
workspace::test_toggle_theme_mode_persists_and_updates_active_themeseeds a static theme, toggles the appearance mode, and asserted the static-to-dynamic migration produced{"light": "One Light", "dark": "One Dark"}— the pre-Omega defaults. It was red onmain, and had been since this delta landed. It now readsDEFAULT_LIGHT_THEMEandDEFAULT_DARK_THEMErather than naming themes, because what that test owns is the migration behaviour and what this delta owns is the values. It also got stronger, not just green. Upstream seeds"One Light"and expects"One Light"in the light slot, so upstream cannot distinguish "the slots were filled from the defaults" from "the seeded static theme was carried into a slot". Under Omega's defaults those are different strings, so the distinction is real; the seed is now a named constant with anassert_ne!against both defaults, so a future default change cannot quietly collapse the test back into that ambiguity.
OMEGA-DELTA-0017 — No competitor's name in the packaged Info.plist
- Upstream Zed:
crates/zed/resources/info/Permissions.plistandDocumentTypes.plistname Zed in thirteen strings — twelveNS*UsageDescriptionvalues andCFBundleTypeName. - Omega, before this: the fork inherited all thirteen verbatim and shipped
them signed and notarized in
0.2.0-rc10.cargo-bundlemerges every file in that directory intoContents/Info.plist(osx_info_plist_exts = ["resources/info/*"]). - Omega now: all thirteen name Omega, and both the source tree and the packaged bundle are gated.
- Why: macOS renders an
NS*UsageDescriptioninside its own permission dialog. The first time Omega asked for the microphone, the operating system told the owner that an application in Zed wanted it — a competitor's product name, system-modal, presented under our Developer ID signature.CFBundleTypeNameshows in Finder's Get Info and Open With menu. See omega#83. - Why nothing caught it:
script/bundle-omega-rcscanned the packaged app for exactly three identity literals (BUZZ_PRIVATE_KEY,identity.key,get_nsec). There was no brand gate at all, so no packaging step had ever readInfo.plist. Every prior brand check on omega#16 compared strings inside the compiled executable, and these strings are not in the executable. The rc5 and rc6 evidence tables were true and the product still shipped it. - The gate reads values, not a list of keys, and walks the whole fragment directory rather than a list of known files, so a brand-new key with a Zed string in a file nobody has heard of fails the same way.
- Enforced by:
no_info_plist_value_names_a_competitorandthe_plist_fragment_parser_reaches_real_valuesincrates/omega_deltas/(source tree),script/verify-omega-brand --appcalled fromscript/bundle-omega-rc(packaged bundle), andthe_packaging_path_runs_the_brand_gate, which fails if the bundle script stops calling it. Policy is shared inscript/omega-brand-gate.json.
OMEGA-DELTA-0018 — No competitor's mark in the shipped icon set
- Upstream Zed: ships
zed_assistant.svg,zed_agent.svg,zed_agent_two.svg,zed_predict*.svgandzed_src_*.svg, several of which draw the Zed Z, behindIconName::Zed*variants. - Omega, before this:
IconName::ZedAssistantandIconName::ZedAgentrendered a Zed logo mark on three status-bar buttons of the running0.2.0-rc10, and the same mark appeared in the conversation view, the sidebar, the model selector and the edit-prediction button. - Omega now: those variants are
IconName::OmegaAgent,OmegaAgentTwo,OmegaAssistantandOmegaPredict*, drawn with the Ω letterform taken verbatim fromassets/images/omega_logo.svg— the same artwork as the app icon — keeping each icon's upstream affordance (the assistant sparkles, the2, the prediction chevrons and arrows, the error cross, the disabled slash).zed_src_custom.svgandzed_src_extension.svgcarry no Z and were renamed tosrc_custom.svgandsrc_extension.svg. ai_zed.svgstays, and is recorded as a third-party allowance inscript/omega-brand-gate.json. It labels the Zed base-keymap preset (beside VS Code, JetBrains and Sublime Text) and Zed's own model provider, exactly asai_anthropic.svglabels Anthropic. Naming somebody else's product is not Omega presenting itself as that product.- Why nothing caught it: a logo carries no text. No scan of the source tree and no scan of the compiled executable can see one, and every brand check on omega#16 through rc6 was a string comparison. See omega#84.
- Why the gate is built the way it is. Two designs were available: pin the
digests of the shipped icons, or forbid competitor-named icon identifiers and
assets. Only the name rule would have caught these three, because digest
pinning catches a change from whatever was pinned, and what would have been
pinned in rc10 is the Zed artwork itself. So the name rule is the gate, over
a complete inventory:
assets/icons/and theIconNameenum are a bijection, enforced by the icons crate's owntest_all_icons_existandtest_no_dangling_icons, and both halves are checked, because renaming only the file leaves the next rebase an identifier to restore the artwork under. The digest pin is kept as well, for the one hole the name rule cannot see: Zed artwork placed inside a correctly named Omega file. - Enforced by:
no_shipped_icon_carries_a_competitor_nameandthe_omega_marks_are_the_reviewed_artworkincrates/omega_deltas/(source tree), andscript/verify-omega-brand --appfromscript/bundle-omega-rc, which checks the packaged executable's embedded rust-embed asset paths and asserts the reviewed artwork bytes are the bytes that were built. - What these gates do not cover. Neither gate can recognise a competitor's
drawing under a name nobody has flagged; the digest pin only says the shipped
bytes are the reviewed bytes, and only for the icons listed in
reviewed_marks. Nothing here inspects rendered pixels..icnsand.pngapp artwork is pinned separately, by the icon-family manifest in the release record, not by this gate. The packaged half runs against the macOS bundle only, so the Linux.desktop, Flatpak, Snap and Windows resources undercrates/zed/resources/are unchecked. And no name is forbidden unless it is written down inscript/omega-brand-gate.json. Rendered review of a candidate is still an owner step, not a mechanical one.
OMEGA-DELTA-0019 — A window with nothing to restore opens on the agent
- Upstream Zed:
restore_or_create_workspaceincrates/zed/src/main.rsanswers a window with no restorable session by callingEditor::new_file(...), so the first thing a new user meets is an empty untitled buffer. The only exception isrestore_on_startup: "launchpad", which opens no content at all. - Omega: the same two call sites call
agent_ui::AgentPanel::open_front_door(window, cx), which focuses the agent panel and activates a new thread. The launchpad behaviour is untouched — overriding it would be Omega ignoring a setting the user set, which is a different bug from the one this fixes. - Why: owner UX direction on omega#76 — "
cmd-shift-aopens the main New Agent Thread screen, and the app defaults to showing that screen — welcome as new agent chat, standard chat input, typing immediately." Omega is an agent product that inherited a text editor's front door. A blank buffer asks the user to already know what they came to do. - Enforced by:
crates/omega_deltas/src/omega_deltas.rs,a_fresh_window_opens_on_the_agent, and the typed rule it mirrors incrates/omega_front_door,launch_surface. - What this delta does not yet deliver. Landing on the agent panel is not
the same as landing on a focused composer.
AgentPanel::activate_new_threadreturns early when no project is open (has_open_project, one of seventeen such guards), and the no-restorable-session path is by definition the no-project case, so a genuinely fresh install lands on the agent panel's "Open Project / Clone Repository" state rather than on a composer. Making a thread bind to a project lazily, on its first workspace-touching action, is the remaining half of omega#76 and is not claimed here. A window that restores a project reaches the composer.
OMEGA-DELTA-0020 — Full Auto is a surface of the chat panel, not a panel of its own
- Omega, before this:
FullAutoPanelwas a dock panel in its own right, registered ininitialize_panelsincrates/zed/src/zed.rs, withDockPosition::Right, a 520px default width, its own Ω dock button tooltipped "Full Auto",activation_priority8, and its ownfull_auto_ui::initregisteringfull_auto_panel::ToggleFocusandfull_auto_panel::OpenLauncheragainst it. The agent panel's new-thread menu held a "Full Auto" item that dispatched the user out of chat and into that panel. - Omega now:
agent_ui::AgentPanelowns a retainedFullAutoPanelentity and renders it as one of its own surfaces. The dock registration is gone, and bothfull_auto_panel::actions are answered by the agent panel, so a keymap or command-palette invocation that worked before still works. The views themselves did not change:crates/full_auto_uistill renders every control it rendered, under a new parent. - Why: owner direction, 2026-07-25 — "I don't actually want a Full Auto panel, it should be folded into whatever the chat UI for Omega is - you can decide how to handle this." Full Auto is one of the three admitted executor classes, so a user starting a lane from chat is the router doing its job. Two destinations for agent work made the user choose a destination before choosing a task.
- Why not a composer mode flag. That is the obvious way to fold a surface
into a composer and it is the wrong one. A flag is a boolean the send path
reads, so anything able to set it can start a run: a slash command, a
restored draft, a model-authored composer insertion. Owner gate 8 says only
an explicit human action may start Full Auto authority. The fold therefore
keeps a dedicated entry and a dedicated Start button — two human gestures —
and moves only where the entry lives.
full_auto_is_not_a_composer_mode_flagincrates/full_auto_uistates the surviving half of that law and now actually checks it. - What the fold costs. Every control survives, which
every_full_auto_affordance_is_mappedincrates/omega_front_doorproves against the source rather than against its author's memory. Two capabilities that were not controls do not survive, and are recorded inFOLD_COSTS: independent dock placement, and reading a run's full detail beside a chat thread at the same time. Active runs still list on the monitor rail, so noticing a run is preserved; reading one in full alongside a thread is not. - The
Panelimplementation is deliberately kept onFullAutoPanel, so a re-dock is a registration line rather than a rewrite. - Enforced by:
crates/omega_deltas/src/omega_deltas.rs,full_auto_is_folded_into_the_chat_panelandonly_a_click_listener_starts_a_full_auto_run.
OMEGA-DELTA-0021 — A thread names the executor that did its work
- Upstream Zed: a thread shows the agent's display name and icon in the panel chrome, and nothing else. That is enough when the panel is Zed's own agent talking to a model the user picked in the same window.
- Omega, before this: Omega presents one chat surface over three executor
classes — the native agent loop, external ACP agents such as
codex-acp, andomega-effectdengine lanes. All three rendered identically. Output produced by another company's coding agent, on another company's model, dispatched by a Full Auto run the user was not watching, appeared in an Omega window and read as Omega's own work. Nothing in the surface said otherwise. - Omega now: every thread carries an executor line above its entries,
naming the runtime class, the executing agent, the provider and model where
the executor reports them, and the engine run where there is one. The line is
rendered from
omega_front_door::ExecutorDisclosureon every draw. - Why: honest attribution before any routing intelligence. Omega Agent is a router that owns routing, disclosure and receipts and owns no execution (omega#74, admitted by the owner 2026-07-25). A router that does not disclose what it routed to is indistinguishable from a first-party agent that did the work itself, and the difference is a claim about authorship.
- Why it is a record and not a string, which is the binding part. The owner
accepted, in the same admission, that the first-party agent does not sign
with its own principal and projects onto the owner's record — on the
condition that disclosure is stored as a typed record that a label renders,
never as a label string. That condition is the only reason the choice stays
cheap to reverse. A record of parts can be handed to a signer later; a stored
line
"engine_lane · codex-acp · run.77"cannot, because recovering the parts means parsing prose, so switching to a signing principal would mean rewriting every thread record instead of adding a signer. A label-string disclosure would silently convert a reversible owner decision into an irreversible one.executor_disclosure_is_a_typed_record_not_a_label_stringasserts the field set exactly, rather than scanning for suspicious names: aline,textorsummaryfield would be a rendered label under a name no denylist anticipated. - Nothing new is persisted, and that is the design rather than an omission.
omega#77's falsifier names a new GPUI-owned durable store as a failure. Every
part of the record already has a durable home — the agent id in
sidebar_threads, the provider and model inDbThread.modelrestored byThread::from_db, the run reference infull-auto-host-correlation.json, reloaded at startup — so the record is a projection over them. A projection cannot disagree with the thread it describes; a cached copy can, and a disclosure that disagrees with its executor is worse than none. - The classification is a checked downcast, not a name match.
agent_id()is a display identifier thatOMEGA-DELTA-0020's neighbour omega#75 is renaming, and that any extension can set to anything. Deciding what ran from it would make the disclosure a string comparison on a label. The fallback for an unrecognised connection isExternalAcp, neverNativeLoop: guessing wrong towards "not ours" costs precision, guessing wrong towards "ours" is exactly the dishonest first-party claim this delta exists to stop. providerandmodelbecame optional here.AcpConnectiondoes not implementAgentConnection::model_selector, so acodex-acpthread has no model to report. With required strings the only options were to fabricate a model or to failis_coherent()on every external thread; the line now says "model not disclosed" instead. An empty identifier stays incoherent, so the distinction between "not disclosed" and "built from a missing value" is preserved rather than flattened.- The binding is an extension trait, not a fork.
AcpThreadis upstream and unchanged:ThreadExecutorDisclosureis implemented for it fromcrates/agent_ui/src/omega_executor_disclosure.rs. A rebase that reshapes the shared thread type breaks theimpland fails the build, rather than silently dropping the disclosure. - What this does not cover. The executor line is on the thread surface. A thread listed in the sidebar, exported, or shared shows its agent name and no executor line. The model is disclosed only where the executor reports it, so most external ACP threads disclose a class and an agent rather than a model. And no check here inspects rendered pixels: the line is asserted to be constructed and drawn, not to be legible.
- Enforced by:
crates/omega_deltas/src/omega_deltas.rs,executor_disclosure_is_a_typed_record_not_a_label_string,the_thread_surface_renders_the_executor_line_from_the_record, andthe_disclosure_is_an_extension_trait_and_not_a_fork_of_the_shared_thread; plusa_restarted_process_still_discloses_the_lane_that_owns_a_threadincrates/agent_ui, which empties the process-local lane index exactly as a process exit does and rebuilds the disclosure from the journal on disk.
OMEGA-DELTA-0022 — No competitor's identity in any shipped asset or any command-palette label
- Upstream Zed: ships
assets/images/zed_logo.svgandassets/images/zed_x_copilot.svgbehindVectorName::ZedLogoandVectorName::ZedXCopilot, declares every application-level action in thezednamespace, and titles the Copilot device-code flow "Use GitHub Copilot in Zed". - Omega, before this: all three shipped in
0.2.0-rc11, signed and notarized, after OMEGA-DELTA-0017 and OMEGA-DELTA-0018 had been added and reported green.- The Zed logo rendered in a release build.
workspace: open component previewwas in the release command palette with no dev gate — the product gatesdev::ToggleInspectoranddev::ResetOnboarding, but not this — and drawing theVectorpreview put the Zed Z on screen. The compatibility allow-list recordedVectorName::Zed*assource_only, meaning nothing rendered it. That was false. - "Use GitHub Copilot in Zed" appeared as a floating-window title bar, as
the modal
Headline, and beside the Zed × Copilot lockup — one user-facing surface, three presentations — and was in no allow-list entry, whileWelcome to ZedandAbout Zedwere listedblocked. Same class, missed. - The
zed:command namespace was user-facing:zed: about,zed: quitandzed: get merchwere visible in the palette while the allow-list entry claimed these "are not user-facing product copy". The targets were already correct (MERCH_URL→ openagents.com, the About window titledAbout Omega); the label and the classification were the defect.
- The Zed logo rendered in a release build.
- Omega now:
- Both images are deleted,
VectorName::ZedLogoandVectorName::ZedXCopilotare gone, theVectorpreview drawsOmegaLogo, the Copilot modal drawsIconName::Copilot, andworkspace: open component previewis registered only underdebug_assertions— hidden from the palette and refused in a release build, the waydev::ToggleInspectoralready was. Removing the artwork and gating the surface are both done, because either alone leaves the other half of the failure standing. - Every presentation of the Copilot surface names Omega. The GitHub Copilot
integration is retained; the "in Zed" framing is not. The claim is
recorded
blockedin the compatibility allow-list, and blocked claims are now read back against the whole tree. - Sixty-six actions moved from the
zednamespace toomega, pluscli::RegisterZedScheme→RegisterAppScheme,feedback::EmailZed→EmailOpenAgents,zed_predict_onboarding::OpenZedPredictOnboarding→omega_predict_onboarding::OpenOmegaPredictOnboarding,zed::OpenZedRepo→omega::OpenRepository(it opens the Omega repository) andzed::OpenZedUrl→omega::OpenAppUrl. Every retired name survives as adeprecated_aliasesentry so an existing user keymap still resolves, and the shipped keymaps dispatch the new names. Thezed-keybind-contextgrammar directory, embedded in the binary and surfaced as the language name "Zed Keybind Context", is nowkeybind-context/ "Keybind Context".
- Both images are deleted,
- Why the previous gate did not catch any of it. OMEGA-DELTA-0018
inventories
assets/icons/*.svgand theIconNameenum.assets/images/*.svgandVectorNameare outside it entirely — and that is exactly where the surviving artwork lived. Nothing had ever read an action declaration, and nothing read the allow-list's ownblockedentries back against the tree. A gate scoped to one directory reports green about that directory and says nothing about the product. This was the third time Zed branding survived a gate that truthfully reported clean: rc5/rc6 scanned the packaged app for three identity literals, rc10 added the packagedInfo.plistand the icon set, and rc11 still shipped all three of the above. - How this inventory is complete rather than enumerated. Each of the four
inventories is derived from the thing that decides what ships, and each
carries an anti-vacuity guard that fails if the derivation stops working:
- Every embedded file. The assets tree plus every directory any
#[folder = "…"]in the repository points at, resolved against the crate root the wayrust-embedresolves it. A rust-embed folder added tomorrow is inside the gate the day it is added. Guards: a floor on the file count, and a failure if no embed declaration is found at all. - Every enum that names an embedded asset. Discovered by finding
format!("<dir>/{…}")for a directory that is in the inventory above, then reading that file's enums.IconNameandVectorNameare both found this way; the policy no longer names a file. Guard:required_discoveriesfails if either stops being found. - Every command-palette label. Every
actions!(namespace, [...])block and every#[action(namespace = …)]derive in the tree — the only two ways to declare a gpui action, so this is the complete set ofnamespace: action namelabels the palette can display. Guards: a floor of 1000 declarations andrequired_actions. - Every blocked public claim. Read out of the compatibility allow-list and
searched for across
crates/andassets/, with four named corpus files exempt (the allow-list and the tests that assert the strings' absence), each asserted to exist so the exemption list cannot quietly grow.
- Every embedded file. The assets tree plus every directory any
- References deliberately kept.
ai_zed.svglabels Zed's base-keymap preset (beside VS Code, JetBrains and Sublime Text) and Zed's hosted model provider, exactly asai_anthropic.svglabels Anthropic — recorded as a third-party allowance in both the icon and embedded-asset sections. Thezed://URL scheme still resolves so existing deep links open.ZED_*environment variables,.zedproject folders and thezed/zed_actionscrate names stay as fork seams. Everyzed::action name survives as a deprecated alias. We are removing Zed as our identity, not erasing that Zed exists. - Enforced by:
no_embedded_asset_carries_a_competitor_name,no_asset_name_enum_carries_a_competitor_name,no_command_palette_label_names_a_competitor,the_retired_action_namespace_still_resolves,blocked_public_copy_appears_nowhere_in_the_treeandthe_component_preview_is_gated_to_dev_buildsincrates/omega_deltas/(source tree),no_vector_name_carries_a_competitor_nameincrates/ui/, andscript/verify-omega-brand --appfromscript/bundle-omega-rc, which scans the packaged executable's embedded asset paths for the forbidden token and asserts the currentomega::action labels were actually built. It rejects the installed0.2.0-rc11onimages/zed_logo.svg,images/zed_x_copilot.svgand three missingomega::labels. Policy is shared inscript/omega-brand-gate.json. - What these gates still do not cover. No gate recognises a competitor's
drawing under a name nobody flagged — the digest pins only say the shipped
bytes are the reviewed bytes, and only for the files in
reviewed_marks. Nothing inspects rendered pixels. Arbitrary user-facing prose is not under a complete inventory: the string half enforces the allow-list'sblockedclaims, which is a written-down list, so a new sentence naming Zed as the product fails only once somebody adds it — that is exactly how "Use GitHub Copilot in Zed" survived, and widening it further needs the 168 remaining brand-bearing prose literals classified, which this lane did not do. Action doc comments, which the palette does not show but the keymap editor does, are unchecked. The packaged half checks action labels by presence of the current ones, not by exhaustive absence: a stripped binary's string table has no separators and no type information, sozed::Aboutappears aszed::AboutOpensand a module path likezed_edit_prediction_delegate::ZedEditPredictionDelegateis indistinguishable from an action name. The absence rule is enforced on the source, where a declaration can be read. The packaged half runs against the macOS bundle only, so Linux.desktop, Flatpak, Snap and Windows resources are unchecked. And no name is forbidden unless it is written inscript/omega-brand-gate.json. Rendered review of a candidate is still an owner step, not a mechanical one. - Falsified. Each defect was reintroduced and the gate watched to fail, then
restored: the artwork back in
assets/images/,VectorName::ZedLogoback on the enum,Use GitHub Copilot in Zedback in the modal,actions!(zed, …)back inzed_actions, and the dev gate removed from the component preview. The widened gate also rejects the installed0.2.0-rc11itself, onimages/zed_logo.svg,images/zed_x_copilot.svgand three missingomega::action labels — the same way the previous gate was proven by rejecting rc10.
OMEGA-DELTA-0023 — The application bundle is stapled, not only the disk image
- Upstream Zed: notarizes and staples the release archive.
- Omega, before this:
script/bundle-omega-rcsubmitted and stapled the DMG only.stapler validate /Applications/Omega.appon the installed product reported no ticket, so Gatekeeper acceptance of the installed application could rest on an online lookup with Apple. - Why it matters: omega#16 requires offline first start. A DMG ticket
covers the disk image the owner throws away; it does not travel with the
application that ends up in
/Applications. Without a ticket stapled to the.app, first launch on a machine with no network is not provably accepted, and the offline-start scope item cannot be closed honestly. - Omega now: the signed
Omega.appis zipped, submitted tonotarytool, and stapled before the disk image is built, so the DMG is assembled from the already-stapled application. The DMG is then signed, submitted and stapled as before. Both are validated withstapler validateafterwards, and the release record carriesnotarization.app_stapledalongsidenotarization.stapledso the two cannot be conflated. - Enforced by:
the_packaging_path_staples_the_applicationincrates/omega_deltas/, which fails if the bundle script stops stapling or stops validating the.app.
OMEGA-DELTA-0024 — Omega Agent is the first-party agent identity
- Upstream Zed: the native
AgentConnection, selector label, component preview, thread placeholder, and evaluation client identify the runtime asZed Agent. - Omega now: those reachable surfaces identify the admitted first-party
orchestrator as Omega Agent and use the reviewed
OmegaAgenticon. The identity symbol isOMEGA_AGENT_ID, renamed along with the value it holds: the icon rename already paid for the lesson that renaming only the string leaves the next upstream rebase an obvious name to restore the old identity under. - Boundary: this delta renames the identity projected by the inherited
native executor. It does not turn
NativeAgentinto the router, make the inheritedtelemetry_idan OpenAgents service identity, change run authority, or claim that the later routing and receipt packets exist. - Telemetry:
NativeAgentConnection::telemetry_idstill reports the inherited"zed"key, because it keys an analytics series and rewriting it would break the series without renaming anything a user sees. The rule is that it stays out of the identity path, and it is now asserted rather than assumed. - Docs: reachable agent documentation names Omega Agent, and the page
moved from
docs/src/ai/zed-agent.mdtodocs/src/ai/omega-agent.md. The file name is checked as well as the contents: falsifying this delta found that restoring the old name passed every check, because a renamed file reads as clean either way. - Kept on purpose:
assets/icons/ai_zed.svgstill labels Zed's base-keymap preset and Zed's hosted model provider,zed_urls.rsstill links Zed's own docs, andgpui_macrosstill records that upstream generated a file with Zed's agent. Removing Zed as our identity is not erasing Zed as a thing that exists; the allowances inscript/omega-brand-gate.jsonname each one with a reason. - Enforced by:
the_first_party_agent_identity_is_omega_agent,no_phrasing_presents_zed_as_the_first_party_agent, andthe_inherited_telemetry_id_is_not_the_product_identityincrates/omega_deltas, plus the existing high-risk public-branding scan incrates/app_identity. - Not covered: all three checks read the source tree. None of them opens a
packaged application, so nothing here proves the shipped
.appis clean — that is the packaged brand gate's job (OMEGA-DELTA-0017/0018), and it scansbrand.words, not this phrase family. The phrase list is a fixed set of substrings: a new way of writing the same claim passes until somebody adds it, exactly as0.2.0-rc10's three-literal scan passed. The scan reaches only the roots and file extensions named in the policy, which is how a.pyfile in the eval harness kept saying "the Zed agent's" through a first pass of this delta. Files outsidescan_roots—.github/,crates/zed/resources/— are unread here. And no check looks at a rendered pixel, so a label that is correct in source and truncated, mis-cased, or absent on screen still passes.
OMEGA-DELTA-0025 — A wrapped harness runs only bytes Omega measured, and only if the pins admit them
- Upstream Zed:
LocalRegistryArchiveAgentresolves whichever version the ACP registry document currently advertises, downloads it into a versioned cache directory, and hands back the command. The registry'ssha256is checked at download time when the document supplies one, and then nothing is recorded: no digest, no receipt, and no way for the owner to say not that version. The extracted tree is not re-read on later launches at all, so a file replaced after the download runs unnoticed. A registry agent runs with the tool permissions of the thread that started it. - Omega now: two gates around the same path, both in
crates/project/src/agent_server_store.rs.- Before anything is fetched,
authorize_version_fetchreads the pin ledger and refuses a version the owner froze out. This is a prefilter, andthe_prefilter_never_admits_what_the_gate_refusesproves it can only refuse what the gate below would also refuse. - After the tree is on disk and before the command is returned,
authorize_installed_harnesshashes every regular file in the installed tree, folds them into one digest bound to their paths, and refuses unless the owner's pins admit that digest. It runs on every launch, not only on install, so bytes replaced after an install receipt was written are caught. Both write a receipt, permitted or refused.
- Before anything is fetched,
- Why a digest and not a version. A pin on a version string is satisfied by
a release re-tagged in place, which is precisely the substitution omega#81's
falsifier describes.
a_retagged_release_does_not_satisfy_a_pinholds that shut. The version is still compared, because a refusal has to name something an owner recognises — but it is not what authorises the run. - Why the receipt is a measurement.
MeasuredDigesthas exactly two constructors,measure(bytes)andmeasure_treeover already-measured digests. There is noFrom<String>, noFromStr, and noDeserialize: a value that arrived as text is not a measurement this host made, and giving it the same type would erase the only distinction that matters. TheAppliedreceipt input takes aMeasuredDigestrather than a string, so a receipt claiming an update was applied structurally cannot be written by a caller that never hashed the bytes.observedAtMsis stamped from onenow_ms()reading taken where the action happened; nothing else that reaches the receipt writer carries a time, so there is no path by which a registry document or a settings file can supply one. - No backfill. A log record from a schema this build does not know decodes
to
ProvenanceUnavailable, which has no digest field, andverify_installationrefuses it. An installation with no receipt at all — every harness installed before this delta — isUnattestedand stays that way until a maintenance action measures it. The schema is read before the strict decoder runs, becausedeny_unknown_fieldswould otherwise classify a genuinely newer record as garbage, and a silent skip is the backfill this contract refuses. - Fails closed. An unreadable pin ledger is not an unpinned machine:
PinState::Unreadablerefuses every action, so truncating one file does not unfreeze every harness. A tree that cannot be measured is refused whether or not a pin exists, because a machine with no pin is not a machine that consented to running unread bytes. Symlinks inside the tree are recorded by path but not followed, so a link planted in the install directory cannot attest bytes from elsewhere on the machine. - Visible. A refusal is an
anyhowerror carryingMaintenanceRefusal::reason(), a sentence that names the pinned version, the version that was refused, and what to do.update_affordancereturnsDisabled { reason }with no way to build a disabled state without one —0.2.0-rc11boundappendSystemNoteto() => {}on the framed provider path, so a refused handoff said nothing in the thread and a different model spent the owner's budget with no trace. A blocked update nobody can see is the same defect. - Enforced by:
a_measured_digest_cannot_be_built_from_a_string,the_external_harness_launch_path_is_gated_on_a_measurement, andthe_enforcement_path_writes_receipts_only_from_decisionsincrates/omega_deltas; 46 contract tests incrates/omega_harness; and 8 filesystem tests incrates/project/tests/integration/harness_maintenance.rsthat drive the real enforcement functions against aFakeFs. - Falsified. Each behaviour was reverted and the check watched to fail, then
restored: the tree measurement replaced with a single-file measurement (the
sidecar test goes red),
PinState::Unreadablefolded intoUnpinned(the corrupt-ledger tests go red), the digest comparison dropped so only versions are compared (a_retagged_release_does_not_satisfy_a_pingoes red), the gate moved below the command it gates (the delta check goes red), andimpl From<String> for MeasuredDigestadded (the delta check goes red). - What this does not cover.
LocalRegistryNpxAgentis not gated: an npx-distributed harness resolves and caches inside the node runtime's own cache, which Omega does not own a directory for, so there is no tree to measure and no gate to hold.LocalCustomAgent— a command the user wrote in settings — is not gated either, and should not be: the user named the binary. Neither the ledger nor the receipt log is signed, so an attacker who can write topaths::external_agents_dir()can rewrite both; this raises the bar from no record to a record that has to be forged, and no further. There is no settings UI for taking or removing a pin yet — the ledger is a file, andMaintenanceAffordanceis the typed state a front-door control will render, not a rendered control. Nothing here verifies a publisher signature: the digest says the bytes did not change since Omega measured them, not that they are the bytes the publisher built.
OMEGA-DELTA-0026 — The shipped defaults reach no Zed service
- Upstream Zed:
server_urlishttps://zed.dev,auto_updateistrue,edit_predictions.provideris"zed", andauto_install_extensionsinstalls thehtmlextension from Zed's extension registry on first start. - Omega:
server_urlishttps://services.openagents.invalid,auto_updateisfalse,edit_predictions.provideris"none", andauto_install_extensionsis{}. - Why: all four landed in one commit,
9e585569cb("Isolate Omega from Zed production services"), and they are one decision rather than four: the settings-layer half of the isolation thatOMEGA_ALLOW_ZED_SERVICESgates in code. Omega has no update feed, no hosted edit-prediction service, and no extension registry of its own, so each of these defaults otherwise points a running Omega at a competitor's production host — with no account, no consent, and inauto_update's case at the one host that can replace the binary. - The telemetry values from that same commit are
OMEGA-DELTA-0004, and were registered when the delta programme started two days later. These four were not, and have shipped unregistered since — including through the0.2.0-rc10and0.2.0-rc11brand reviews, which read icons, plists, actions and binaries, and never read a settings value. disable_aiis not in this set. The isolation commit also set ittrue;87703b753aset it back tofalsewhen registry ACP agents were enabled, so it matches upstream today and is not a divergence. The comment above it still differs, which is prose, not policy.- Enforced by:
default_settings_enable_registry_acp_without_enabling_zed_productionincrates/app_identity/src/service_isolation.rs, which has asserted all four since the isolation commit and is the primary check; plusthe_service_isolation_defaults_are_still_the_omega_valuesandthe_service_isolation_test_still_asserts_the_registered_defaultsincrates/omega_deltas/. - Why there is a second check, when the rule is to cite rather than
duplicate. Citing alone fails two ways here, and both are the failure this
file exists for.
- The cited assertions can be deleted, and deleting an assertion turns a
test green.
auto_updateandauto_install_extensionsread as off-topic inside a test named for Zed service isolation and are exactly what a tidy-up removes.the_service_isolation_test_still_asserts_the_registered_defaultspins them, and pins the delta ID beside them. cargo test -p omega_deltasis the command this registry tells a reader to run. A delta whose only value assertion lives in another crate's test is green under that command while the value is reverted — a mechanism reporting green about less than the reader assumed, which is precisely the shape of every miss recorded above.
- The cited assertions can be deleted, and deleting an assertion turns a
test green.
- Not covered: these are defaults. A user settings file, a project
settings file, or an environment variable still overrides every one of them,
and
ZED_SERVER_URLoverridesserver_urlwithout touching any file. This delta says what Omega ships, not what a running Omega cannot be told to do.
OMEGA-DELTA-0027 — Codex ACP is configured out of the box
- Upstream Zed:
agent_serversis{}. An external ACP agent is something the user adds. - Omega:
agent_serversdeclarescodex-acpwith"type": "registry", so it resolves from the ACP registry atcdn.agentclientprotocol.com— anapprovedhost incrates/app_identity/fixtures/endpoint_allowlist.json. - Why:
bc87aec95crouted Full Auto through Codex ACP, which makes this not an optional extra. It is one of the three executor classesOMEGA-DELTA-0021exists to disclose, and a Full Auto lane dispatched at an agent that is not configured does not fall back — it fails. Shipping it configured is the difference between Full Auto working on first launch and Full Auto reporting a missing agent. - Stated plainly: this is a default that reaches a third-party network
service. It is not covered by
OMEGA-DELTA-0026and is not meant to be — that posture is about Zed's production services, not about Omega making no requests at all.codex-acpis an npx-published registry agent, so the first turn on it reachescdn.agentclientprotocol.com,registry.npmjs.organdnodejs.org— all threeapprovedin the same allow-list. A genuinely offline first start therefore does not get Codex. The offline-start requirement on omega#16 is about launching, not about every executor being reachable. - Enforced by:
codex_acp_is_configured_by_defaultincrates/omega_deltas/, and theagent_serversassertion indefault_settings_enable_registry_acp_without_enabling_zed_production, whichthe_service_isolation_test_still_asserts_the_registered_defaultskeeps in place.
OMEGA-DELTA-0028 — The default icon theme is Omega's own
- Upstream Zed: the built-in icon theme is
Zed (Default), in bothDEFAULT_ICON_THEME_NAMEand the shippedicon_themesetting. - Omega: both are
Omega (Default). - Why: the owner opened
~/.config/omega-rc/settings.jsonand it introduced the product as Zed (3493676d71). A settings file the owner opens is a product surface, and omega#16 forbids presenting Zed as the product there. The name is also what the icon-theme selector displays. - Why the check is about agreement rather than about the string. The two
values are coupled:
configured_icon_themelooks the settings value up in the registry, and the registry's only built-in icon theme is registered underDEFAULT_ICON_THEME_NAME. A rebase that reverts one and not the other breaks nothing visible —crates/theme_settings/src/theme_settings.rslogs the lookup failure and falls back — so the product keeps working while shipping a competitor's name in the file the owner reads. Pinning the literal in a third place would catch a revert of both and miss the half-revert entirely. The check therefore asserts the two agree, and then asserts neither names a competitor, using the samescript/omega-brand-gate.jsonword list as the packaged gate. base_keymap: "Zed"deliberately stays, and is why the check reads one key instead of scanning the settings file for brand words. That value names Zed's keybinding scheme, offered beside VS Code, JetBrains and Sublime, exactly asai_zed.svglabels Zed's own model provider. Renaming it would misdescribe what the setting selects.- Not covered, and deliberately not registered: the comments in
assets/settings/default.json. Four of them were reworded from Zed to Omega alongside the value changes above (3493676d71,9e585569cb), and roughly sixty-five other lines in that same file still describe inherited behaviour by naming Zed. Registering the four would assert a policy — "the shipped settings comments say Omega" — that is not true of the file and that no check could enforce without classifying the other sixty-five, which is the prose-classification workOMEGA-DELTA-0022explicitly records as not done. They are drive-by edits, so they are flagged here rather than blessed with an ID. This delta covers the icon theme's name, which is a value the product renders into a selector and writes into the owner's settings file. - Enforced by:
the_default_icon_theme_is_omegasincrates/omega_deltas/.
OMEGA-DELTA-0029 — Omega Agent routes deterministically, fails closed, and records why
- Upstream Zed: a thread is bound to whichever agent connection created it, for its whole life. There is one executor per thread and no decision to make, so there is nothing to explain and nothing to record.
- Omega, before this: Omega presents one chat surface over three executor
classes, and which one a thread got was decided implicitly by which panel
entry the user happened to open.
OMEGA-DELTA-0021made a thread name its executor; nothing yet chose it on purpose, and nothing wrote down why. - Omega now:
omega_front_door::routeris the routing law — a pure function from typed inputs (a user pin, the engine's last framedget_capacityanswer, and which executors are connected) to a typedRouteDecision.agent_ui::omega_router::OmegaAgentConnectionis the dispatch half: it implementsAgentConnectionand hands every method to the executor the decision names. - Pins are honoured. An explicitly pinned executor that can serve is always used, whatever else is ready. A pin outranks an idle engine lane, because the engine being free is not a reason to move a turn a person placed.
- Engine-down fails closed to the native loop, and says so. Every way the
engine can be unavailable — not running, timed out, an answer this build
cannot read, at its active-run limit, no ready lane, a named lane that is
busy, no executor connected for lanes — lands on the native loop with a typed
fallback reason, keeps the pin it could not honour, and renders a line that
says a pin was not honoured. A fallback the user cannot see is the same defect
class as a handoff with no system note, which shipped in
0.2.0-rc11becauseappendSystemNotewas bound to() => {}on the framed path. - The decision is recorded. Every decision is written to
agent-route-journal.jsonunder the Omega data directory in a canonical form that round-trips back into a typed decision, keyed by session, rewritten atomically. It carries no clock: a timestamp would make two identical decisions look different and would put a non-deterministic value beside a decision path whose whole point is that it is reproducible. A record that reads cleanly but describes an impossible decision — a fallback that claims an engine lane, an honoured pin naming a different class from the one that ran — is rejected rather than believed. - Determinism, and why it is not just a unit test. The routing law reads
nothing but its argument, walks only ordered slices, and resolves a choice
among equally ready lanes by a total order on the lane reference rather than
by the order the engine listed them — the engine's array order is not a stable
input, so "the first available lane" would route the same thread two ways on
two runs with nothing wrong with either.
the_routing_law_has_no_clock_no_randomness_and_no_hash_orderreads both source files for clocks, randomness, hash-map iteration, and the environment, because a behavioural test can only show that the inputs it happened to try agreed twice. - An unpinned thread never reaches an engine lane, on purpose. Owner gate 8
says no model-initiated path may start Full Auto authority, wherever that
action lives. An engine lane is Full Auto authority, so a router that
preferred a ready lane for an unpinned thread would be exactly that
forbidden start, through a door nobody had flagged — which is how
full_auto_enablesurvived until it was removed today. v1 therefore routes an unpinned thread to the native loop, always, and engine lanes are reachable only through a pin a person sets on a visible control. Model-advisory routing is out of scope for v1 by the packet's own terms; this is the shape that keeps it out. - The router owns no execution, and that is read off the source.
the_router_owns_no_execution_and_starts_no_runscans the dispatch file for execution vocabulary and for run-control verbs;the_router_delegates_every_agent_connection_methodparses theimpl AgentConnectionblock and fails if any method stops handing its work to an executor. A method that quietly grew a turn loop would still compile, still pass every behavioural test that did not call it, and still read as a router from its own module docs. omega-effectdstays the sole run authority. The engine's capacity answer is read, never written back, never cached as run state. The router projects; it does not own. A later engine answer does not rewrite a decision already recorded, so a turn does not move executors mid-thread because capacity changed between turns.- A routed thread carries the executor's connection, not the router's.
OMEGA-DELTA-0021classifies a thread by downcasting its connection, so a thread carrying the router would disclose the router as its executor — the exact first-party attribution claim omega#77 exists to stop. - Disclosure grew a part, not a caption.
ExecutorDisclosuregainedroute: Option<RouteReason>, a closed typed set, added toEXECUTOR_DISCLOSURE_FIELDS.Nonemeans the thread was not routed by the router, which is different from claiming a reason nobody recorded. - Enforced by:
the_routing_law_has_no_clock_no_randomness_and_no_hash_order,the_router_owns_no_execution_and_starts_no_run,the_router_delegates_every_agent_connection_method, andthe_route_decision_is_a_record_that_round_tripsincrates/omega_deltas; the routing-law suite incrates/omega_front_door/src/router.rs; and the dispatch and journal suite incrates/agent_ui/src/omega_router.rs. - Not covered. The wiring this entry once listed as missing landed in
OMEGA-DELTA-0035: the native agent entry now resolves to anOmegaAgentConnection, the panel pollsget_capacityintoobserve_capacity, and a pin menu sits on every thread's disclosure line. ReadOMEGA-DELTA-0035for what that wiring does and does not reach. Separately, the router can decide an engine-lane route it cannot itself dispatch, because engine lanes are started by a person on the Full Auto surface and driven by the host bridge rather than throughAgentConnection::prompt; that gap is the namedengine_lane_not_connectedfallback rather than a substitution. And no check here looks at a rendered pixel, so a route line that is correct in source and truncated or absent on screen still passes.
OMEGA-DELTA-0030 — A linked run shows its receipt chain in the thread
- Upstream Zed: an agent thread shows the turns the agent produced. There is no engine, no run authority, and nothing to link to, so there is nothing upstream to revert to here — only something to quietly leave out.
- Omega, before this:
OMEGA-DELTA-0021gave every thread an executor line, and a thread executed by anomega-effectdlane names its run in it. Naming a run is not showing one. The reader was handed a reference and left to go somewhere else to learn whether the work was host-verified, refused, or merely claimed — and on the Full Auto surface, where the chain did render, a broken chain rendered as one sentence: "Evidence chain unavailable or cross-links did not verify." Four distinct situations, one word. - Omega now: a thread an engine lane executed renders, above its entries,
the run's reference, the agent the run delegated to, the run's lifecycle, and
its receipt chain — the nine omega#43 hops in normative order when the chain
is complete, and
chain: unavailablewith a named reason when it is not. The rows use the same label/value grammar as the receipt inspector, so a chain in a thread reads like a chain in the receipt pane rather than like a second format. - A refusal is shown, never hidden and never rounded up. The four
record-level reasons are not interchangeable.
hop_missingsays the host never produced the step;hop_mismatchedsays two records tell two stories about one run;hop_privatesays the host produced it and this surface may not carry it;self_reportedsays the run vouched for itself. Collapsing them is how a contradicted chain gets read as merely incomplete — the exact confusion omega#47's reason vocabulary was written to end. And a broken chain still draws rows: a surface that renders nothing when it cannot verify has told the reader nothing, and silence reads as "no run". One malformed record must not blank the surface. - The engine stays the sole run authority, and staleness is the proof.
omega#80's falsifier is "a run's source of truth ends up in a panel entity".
The thread stores the engine's records and the instant it read them, never
a projected link, and re-derives the link on every draw. Past
THREAD_RUN_LINK_MAX_AGE_MS— five missed reads of a three-second poll — the link rendershost_unavailableinstead of the last chain it saw. A cached conclusion would have quietly outlived its source; a cached record with an expiry cannot. A state the contract does not model is not translated into the nearest one either: a run reportingacknowledgedreports no state at all, because a relay's acknowledgement is a statement about a message, not about work. - A terminal state is not a receipt.
ThreadRunLink::is_receiptedrequires a complete chain and an allowing authority decision. A run whose engine state issucceededand whose chain is unavailable renders both facts and is not claimed as receipted; a chain that resolves toallowed: falserenders complete and is still not receipted. Together those are the second half of omega#80's falsifier. - The chain comes from the omega#47 producer, not from a second
implementation.
workroom_receipts::project_issue31_evidence_pairis the single-pair entry point to the same code the phone's projection is built from, and it routes its output back through the adjunct's own decoder — so a hop this surface may not carry is refused rather than shown, and the desktop and the phone cannot hold two opinions about one run. Writing a second chain reader would have passed every other check in this repository and still drifted. - Dispatch became a typed command. The start request used to be a
json!blob built inline in the render file: its fields were whatever that expression happened to contain, and the only proof it carried no evidence was that nobody had added any.FullAutoDispatchis now the record, its field set is asserted exactly, and it has no field for anevidenceblock, adecisionRef, or anauthorityReceiptRef. omega#47 watched a live engine ignore all three, forged, in a real start request; this makes the same claim one layer earlier, where the forgery cannot be written at all. - Owner gate 8 is enforced by the argument type.
FullAutoDispatchhas one constructor and it takes anomega_front_door::LaunchOrigin, every variant of which is a control a person operates. There is noLaunchOrigin::ToolCall, so a model-authored path cannot produce a dispatch, andno_model_callable_crate_can_dispatch_full_autochecks that no crate outside the Full Auto surface can even name the command. - The refusal that replaced a string test. "No worktree" used to be decided
by testing whether a formatted reference ended in
"missing", which refused a real project whose name ended that way and accepted an unsafe one. It is a typedDispatchRefusalnow, and the honest case is covered by a test. - What this does not cover. The thread's run link is read-only. Pause,
resume, stop and retry stay on the Full Auto surface, where each control is
bound to the run generation the host minted it for; a second set of buttons
reading a projection would be a second place that believes it can command a
run. The
NewThreadMenuItemorigin is not distinguished in practice, because that menu entry dispatches the sameOpenLauncheraction as the command palette, so both recordopen_launcher_action. Only threads the host bridge correlated to a run carry a run reference at all, so a run a person watches only on the Full Auto surface renders its chain there and not in a thread. And no check here reads a rendered pixel: the rows are asserted to be built and drawn, not to be legible. - Enforced by:
a_full_auto_dispatch_carries_no_evidence,no_model_callable_crate_can_dispatch_full_auto,a_thread_renders_the_receipt_chain_of_its_linked_run, andthe_thread_run_link_is_a_projection_and_not_a_second_authorityincrates/omega_deltas; plus the falsification suites incrates/full_auto_ui(thread_run_link,dispatch) andcrates/workroom_receipts(the_single_pair_entry_point_names_each_refusal).
OMEGA-DELTA-0031 — No user-facing sentence presents a competitor as the product
- Upstream Zed: names itself throughout its own copy, which is correct for Zed and is inherited wholesale by a fork.
- Omega, before this: the signed, notarized
0.2.0-rc13still told the user, in its own voice:Click 'Connect' below to start using Ollama in Zed— and the identical llama.cpp line. Provider onboarding, one click from the model picker.Checking for Zed Updates…/Downloading Zed Update…/Installing Zed Update…in the title bar.<title>Authorization Successful — Zed</title>and aZedbrand line on the OAuth callback page rendered in the user's browser.You are the Zed coding agent running inside the Zed editor.— the system prompt, i.e. the identity handed to the model on every turn.# ====== Auto-added by Zed: =======, written into the user's.git/info/exclude.Open with Zedin the Windows Explorer context menu,Error: Running Zed as root…,Zed managed Node.js,Request blocked by the Zed sandbox network policy.,Zed: v{version}in the system specs a user pastes into a bug report, and ~forty settings-schema descriptions the settings editor renders as tooltips (Settings related to calls in Zed,Configuration of voice calls in Zed., …).- Every brand check on omega#16 passed while all of that shipped.
- Why the previous gate did not catch it. OMEGA-DELTA-0022 closed assets,
asset-name enums and command-palette labels with derived inventories, and
named this class as the one it could not close: its string rule enforces
the compatibility allow-list's
blockedclaims, which is a written-down denylist. A new sentence fails only once somebody adds it — which is exactly howUse GitHub Copilot in Zedsurvived — and 168 brand-bearing prose literals were left unclassified. - Omega now: the default is inverted. Every brand-bearing prose literal in
a derived inventory must be classified in
script/omega-brand-gate.json; an unclassified one fails. A new sentence is unclassified the moment it is written, so it fails on the commit that adds it rather than on the release that ships it. Two hundred and seventy lines of copy across 94 files were rewritten to Omega, and 56 literals are recorded as deliberate references to Zed with a class and a reason (4 of them exist only in the package). - The rule, for product claim versus third-party reference. Substitute our
own name. If the sentence stays true with
Omegain place of the brand, the brand was standing where our product's name belongs and it is a product claim — rewrite it.start using Ollama in Zed→start using Ollama in Omegais true, so it was a claim about us. If the substitution makes the sentence false, it states a fact about somebody else's product, service, documentation, or authorship — keep it.similar to Zed's default keybindingsdoes not become true of Omega's keybindings, so the preset really is describing Zed. The five classes in the policy are the reasons a substitution would have been false:zed_product,zed_service,zed_authorship,fork_seam,omega_contrast. - How this inventory is complete rather than enumerated. Five streams, each
derived from a mechanism that exists in the tree:
- Every Rust string literal under
crates/, including raw and multi-line ones, outside#[cfg(test)]items and test files. A literal is compiled in; nothing can prove one is never rendered, and assuming otherwise is what left the provider copy standing through four release candidates. The lexer matters: a regex over single lines misses exactly the literals carrying the longest copy — the OAuth page, the run-as-root warning and four provider error toasts are all multi-line. - Every settings-schema description: doc comments in a file that really
derives
JsonSchema, which is howschemarsturns them into the schema'sdescriptionvalues and how the settings editor renders them as tooltips. Doc lines are stripped before the derive is looked for, so a derive written inside a rustdoc example does not drag a framework crate's internal documentation into the inventory. - Every action description: doc comments inside an
actions!(…)body or above an#[action(…)]derive — the text the keymap editor shows. OMEGA-DELTA-0022 recorded these as unchecked. - Every
--helpline: doc comments in a file derivingParser/Args/Subcommandor using#[command(…)]. - Every shipped asset line, over the embedded-asset inventory
OMEGA-DELTA-0022 already derives — keymap and default-settings comments,
the agent prompt templates, themes.
A literal enters the inventory when it carries a
brand.words/brand.substringshit and is prose-shaped: three tokens or more, at least two plain alphabetic words. That is the one judgement in the derivation, and it is deliberately loose —Zed Plex Sansis three words and is in the inventory, classified, rather than quietly filtered away.
- Every Rust string literal under
- Anti-vacuity. The floors are on what the scanners read, not on what
they find, because a clean tree finds almost nothing and a broken parser
finds nothing, and those two must not look alike: 1500 Rust sources, 100 000
string literals, 6000 schema doc lines, 1200 action doc lines, 300
--helpdoc lines, 400 embedded files. Separately, every classified entry is asserted to still be present, so the registry cannot become a graveyard and a scanner that stops reading a stream fails on that stream's entries. - The two halves are checked against each other.
crates/omega_deltasandscript/verify-omega-brandimplement the inventory independently in Rust and Python from the one policy file. Dumped and diffed on this tree they produce byte-identical inventories — 90 literals, same kind, file, line and text — which is the drift guard a shared policy file only half provides. The two lexers disagree on six string literals out of 135 000 on an edge case in char literals; none carries a brand, and the counts are only used as floors. - The packaged half reads values, not source. Assets and literals survive
in the executable, so the shipped binary is scanned directly: it does not
honour
#[cfg(test)], does not care which crate a string came from, and sees generated files — the licence attribution page is gitignored and exists only in the package, which is whereCopyright 2022 - 2024 Zed Industries, Inc.comes from. A stripped string table has no separators, so the scan is anchored on each brand occurrence and reports one only when the brand is written as a word in running text and no classified sentence spans that position. Classified entries are compared as the compiler leaves them: a\continuation joins two lines with no separator and a\nsplits the run, so the fragments are matched, not the source spelling. - Two live defects fell out of the inventory rather than out of a search.
f10on Linux and Windows was bound to["app_menu::OpenApplicationMenu", "Zed"], naming a menu that has beenPRODUCT_NAME— "Omega" — since the rename: the key did nothing. And renaming the.git/info/excludemarker without reading the old one back would have stranded an inherited-marker block in the user's repository, still excluding files from git with nothing left that knew how to remove it, soGitExcludeOverridenow cleans up both. - References deliberately kept, each with a class and a reason in the
policy: Zed's hosted service, account, plans, billing and servers
(
Zed Pro Plan,Business Plan - Zed models enabled,Signs in to Zed account.,Zed's Edit Predictions, the whole Zed Cloud provider); Zed's own documentation (zed.dev/docs/...in remote-development, keymap, Linux and Windows troubleshooting copy); Zed's authorship of the inherited One/Ayu/Gruvbox themes and the Windows Performance Recorder profile; theZed Plex Sans/Zed Plex Monofamily names recorded inside the shipped font files; the retired.git/info/excludemarker, read back for cleanup; and Omega-authored copy that names Zed in order to say how Omega differs from it.Enable Fast Mode for Zed?was the one genuinely ambiguous case — it read as the application — and becameEnable Fast Mode for Zed AI?, naming the service the toggle and its billing actually belong to. We are removing Zed as our identity, not erasing that Zed exists. - Enforced by:
no_unclassified_prose_names_a_competitorandthe_prose_lexer_reads_multi_line_and_raw_literalsincrates/omega_deltas/, andcheck_prose_inventory/check_packaged_proseinscript/verify-omega-brand, whichscript/bundle-omega-rcalready runs against the built bundle. The packaged half rejects the installed0.2.0-rc13on 200 distinct windows, every one of which is prose this delta rewrote. - Falsified. A new sentence naming Zed as the product was added to a
provider page and to
assets/settings/default.json; both halves failed as unclassified and both recovered when it was removed.Click 'Connect' below to start using Ollama in Zedwas restored verbatim and both halves failed again. A classified entry was deleted from the policy and the surviving literal failed; the entry was pointed at a sentence that is not in the tree and the staleness assertion failed. Each floor was raised above the observed count in turn and the corresponding guard fired. And the packaged half was run against the signed, notarized0.2.0-rc13in/Applications, which it rejects, and against a stub bundle whose binary holds no strings, where its own vacuity guard fired. Rebasing onto seven newly landedassets/settings/default.jsoncomments naming Zed failed the gate on all seven until each was classified — the mechanism working on somebody else's concurrent change rather than on a planted one. - What this still does not cover. The scan reads
crates/and the embedded assets;docs/,.github/,script/andcrates/zed/resources/are outside it, so a Zed sentence in the docs site or a workflow file passes. Prose-shape is a heuristic: a one- or two-word label likename = "zed"in the CLI's clap#[command]is not prose and is not seen — that identifier still spells the old name and is a known residual. Nothing reads a rendered pixel, so a sentence that is correct in source and truncated on screen still passes. The packaged half runs against the macOS bundle only, so Linux.desktop, Flatpak, Snap and Windows resources are unchecked.#[cfg(test)]exclusion is a source-side convenience whose only real backstop is the packaged scan. And no name is forbidden unlessbrand.wordsorbrand.substringssays so: this delta is about how completely a forbidden name is looked for, not about which names are forbidden.
OMEGA-DELTA-0032 — A send during a running turn has one declared answer per executor
- Upstream behaviour.
ThreadView::sendchecks whether a turn is running and, if so, queues the message.MessageQueuealready tells a steer from an enqueue, andsync_queue_flag_to_native_threadsetsend_turn_at_next_boundaryonagent::Threadwhen the front entry wants to steer. That function no-ops for anything that is not a native thread, anddispatch_queued_entrythen cancels the running turn unconditionally before sending. - Why Omega diverges. Those two facts together mean one button does three
different things. On the native loop a steer ends the turn at a message
boundary. On an external ACP peer and on an engine lane the same gesture
cancels the running turn and starts a new one — a behaviour nobody declared,
nobody negotiated, and the user cannot distinguish from steering. Omega runs
three executor classes on purpose (
OMEGA-DELTA-0029), so "two work and one silently drops" is not a rough edge here, it is the concurrency hole omega#79 names at design time. - The law.
omega_front_door::dispositionis a total const function from (command, executor class, declared steer capability) to a declared outcome. There is no fallthrough and no variant meaning "whatever the executor does". A steer the class cannot honour is a typed refusal that carries its fallback, so a refusal cannot be constructed without saying what happened to the message.- The native loop steers at its message boundary. Omega owns both sides of that loop, so it does not negotiate.
- An external ACP peer is asked. The Agent Client Protocol has no capability for mid-turn delivery, so every peer today answers "unknown" — and unknown is refused, not assumed. Silence is not a capability, and the cost of guessing wrong is the user's running turn.
- An engine lane refuses whatever the engine can do. An engine lane is Full
Auto authority, and
OMEGA-DELTA-0030keeps a run's controls bound to the generation the run surface minted them for. A composer that could interrupt a run would be a second surface that believes it can command one.
- Durable admission. The queue is written down before the composer
acknowledges it.
openagents.omega.agent_send_queue.v1is keyed by thread and item, ordered by an admission sequence rather than by map order, rewritten atomically, and refuses a document it did not write. A terminal item is never reopened:promoted,cancelledandfailedare final, because a restart that could move an item back toqueuedwould promote it twice. Promotion needs proven quiescence — after a reconnect Omega never saw the prior turn stop, and promoting there is how a queued message races the turn it was meant to follow. - The disposition is derived, never stored. The same rule
ExecutorDisclosureholds to. A stored disposition could disagree with the law that produced it, and then the record would be the lie. The journal holds the parts; the phrase is a function of them. - What this does not cover. The queue's live half still lives on the view, so the durable record is authority for what was admitted and not yet for the editor state a restart would need to rebuild the composer rows. Nothing here reads a rendered pixel. And an external peer's capability is a single call site returning "unknown" — when ACP gains a mid-turn capability, that call site is what changes, and the law above already has the variant for it.
- Enforced by:
the_send_during_turn_law_answers_for_every_executor_class,the_queue_law_and_its_journal_read_nothing_but_their_inputs,the_composer_decides_a_mid_turn_send_through_the_law, andthe_send_queue_is_a_durable_record_and_not_renderer_memoryincrates/omega_deltas; plus the suites incrates/omega_front_door/src/send_during_turn.rsandcrates/agent_ui/src/omega_send_queue.rs.
OMEGA-DELTA-0033 — A pin is a control a person can press, and a refusal is a sentence they can read
Upstream: an external agent's row in Settings shows a name, a source icon and a Remove button. There is no version pinning, no provenance, and nothing to say what bytes a wrapped harness will run with the thread's tool permissions.
Omega before this delta: OMEGA-DELTA-0025 (omega#81) built the whole
decision layer and rendered none of it. MaintenanceAffordance::Disabled
structurally could not exist without a sentence, and nothing put that sentence
on a screen. A refusal reached the owner only as agent-launch error text. There
was no writer for the pin ledger in production code at all —
HarnessPinLedger::set_pin and remove_pin were called only by tests, so a
"pin" was a JSON file the owner had to hand-edit. Two of the four maintenance
actions omega#81 named did not exist. And LocalRegistryNpxAgent consulted
nothing: pinning an npx harness did nothing whatsoever, which matters more
than it sounds, because the harness omega#81's acceptance sentence names —
codex-acp — is npx-distributed in the live ACP registry.
Omega now:
- One control, never two.
PinControloffers exactly one ofTake,Remove, orUnavailable { reason }per harness. Re-pointing a freeze at whatever is installed now is deliberately two actions, because one click that silently moved a pin would undo the freeze in the exact case it exists for.Unavailablecarries its reason by construction, for the same reasonDisableddoes: omega 0.2.0-rc11 shipped a refusal nobody could see. - The row cannot disagree with the gate.
harness_front_door_stateroutes every answer through the samedecide_maintenance/admits_version/admits_package_manager_launchthe launch path enforces, andthe_rendered_launch_state_equals_what_the_gate_would_decideasserts equality across the whole space of pin states and measurements. The settings page calls none of those functions itself — it matches on the result and writes no sentence of its own. - A pin is taken at bytes, through the gate.
pin_installed_harnessobtains its digest fromauthorize_installed_harness, so taking a pin runs the real gate, writes a real receipt, and cannot freeze a tree the gate would refuse. An unreadable ledger refuses both controls rather than being rewritten from the subset this build could parse — that is not removal, it is deletion of everything unreadable. - The npx path consults the pin. There is no tree to hash, so the measured
gate cannot run;
admits_package_manager_launchnarrows the question to the one the ledger can answer. A pinned harness refuses with a sentence naming the resolver, and the refusal is recorded. The honest limit, stated rather than hidden: this raises no bar on an unpinned npx harness, which still launches unattested — the front door says so on the row. - Resolving the channel and re-probing are their own actions. Channel
resolution happens when nothing is about to launch, so a frozen harness is no
longer offered a version the next launch would refuse — and the resolution
that decided so is recorded, because an update that never starts leaves no
other trace.
ReprobeCapabilityis what the owner's control does with nothing about to run, kept distinct fromVerifyso the log can say whether a measurement was taken because something was about to execute or because a person asked. - Proven live.
live_a_real_registry_install_produces_a_receipt_and_a_pin_blocks_the_next_versionfetches the live ACP registry, downloads a real release through the same downloader the launch path uses, gates the extracted tree, reads the receipt off a real disk, pins it, watches the pin block a later version, and then adds one file to the installed tree and watches the harness stop running. It is#[ignore]d: a suite that silently depends on a third party's release assets goes red for reasons that are not about this repository. - What this does not do. Neither the ledger nor the receipt log is signed;
anyone who can write to
paths::external_agents_dir()can rewrite both. The digest says the bytes did not change since Omega measured them, not that they are the bytes the publisher built. And an owner-named custom binary has no maintenance state at all, by design — Omega did not choose it and does not update it. - Enforced by:
the_front_door_page_renders_decisions_it_did_not_make,a_withheld_control_carries_a_sentence_all_the_way_to_the_widget,the_pin_ledger_has_a_writer_the_owner_can_reach,the_package_manager_launch_path_is_gated_on_the_pin,resolving_a_channel_is_a_recorded_action_that_gates_the_offer, andthe_front_door_measures_the_tree_the_launch_path_gatesincrates/omega_deltas; plus the suites incrates/omega_harness/src/front_door.rsandcrates/project/tests/integration/harness_maintenance.rs.
OMEGA-DELTA-0034 — The front door works with no project open
- Upstream Zed: the agent panel requires an open project.
agent_ui: Require an open project for agent panel(#56577, "a bit brute force, but it works") put ahas_open_projectearly return in front of every entry to the panel, so a window with no worktree shows "Open a Project" and nothing else. That is coherent for an editor whose agent is an accessory to a project. - Omega, before this:
OMEGA-DELTA-0019made a window with nothing to restore open on the agent instead of on an untitled buffer, andOMEGA-DELTA-0020folded Full Auto into that panel. Both landed. The exit omega#76 actually asked for — fresh launch lands on the surface and typing starts a thread — did not: a window with nothing to restore is by definition a window with no project, so the front door opened onto "Open Project / Clone Repository" and there was no composer to type into. The landing half shipped and the typing half did not, and the two were reported together. - Omega now: the guards on the front door's own path are gone.
activate_new_thread,activate_draft,new_thread,ensure_native_agent_connectionandtoggle_new_thread_menuno longer refuse a projectless window, the toolbar's create controls are live, and a thread's title is editable. Typing on a fresh install starts a real thread. - What the guards protected, checked rather than assumed. The one that could
plausibly have been load-bearing was
ensure_native_agent_connection, and it is not:NativeAgentServer::connecttakes the project as_projectand never reads it, andNativeAgent::new_sessionbuilds a thread from the project entity without requiring a visible worktree. What the guard bought was not spinning up a connection for a window upstream had decided would never show the agent — a resource choice resting on a premise Omega does not share. - The workspace-touching guards stay. A terminal genuinely needs a working
directory, so
should_create_terminal_for_new_entrykeeps its check and a projectlessnew_threadfalls through to a thread rather than a terminal. Loading a thread from the clipboard, resuming a persisted draft, refreshing skills, initialising from a source workspace, and starting an external ACP agent all still require a project. Removing those would not be project-optional threads; it would be threads that fail later and less legibly. cmd-?gave the agent panel back to macOS.agent::ToggleFocuswas bound tocmd-?, which is macOS's reserved Help chord — the Help menu's search field. Omega cannot win that keystroke, so the binding was a keybinding that looked present and did not work. It isctrl-cmd-anow: free, not system-reserved, and on the same letter ascmd-shift-a. Linux (ctrl-?) and Windows (ctrl-shift-/) are untouched, because neither is reserved there and changing them would be churn with no defect behind it.- The rendered proof, and why the runner needed standing up.
zed_visual_test_runnerwas already in the fork — macOS headless Metal capture, no Screen Recording permission, no window to get frontmost — and it had no committed baselines and no invocation, so no Omega packet had ever used it.script/omega-visual-proofis the invocation,OMEGA_VISUAL_ONLY=1runs Omega's suite alone, and theomega_*baselines are re-included in.gitignoreand committed. A baseline nobody committed cannot fail. The suite asserts the rendered line's text through the same method the render calls and asserts the record is coherent before each capture, so a picture can never be the only thing standing behind a claim. - Enforced by:
the_front_door_does_not_require_an_open_projectandrequired_keymap_bindings_resolveincrates/omega_deltas;test_empty_workspace_opens_the_front_doorincrates/agent_ui; the rendered proofsomega_front_door_no_projectandomega_front_door_typingincrates/zed/src/visual_test_runner.rs. - What this does not cover. A first-ever launch lands on the Onboarding
tab, not on the agent — observed on a packaged build with a fresh
--user-data-dir, where the front door is behind onboarding and the agent dock is closed until it is finished. Every launch after that lands on the agent. That ordering was left open here as a question for the owner; it is now decided and recorded asOMEGA-DELTA-0040, which tests the handoff from onboarding to this front door. A projectless thread is also not yet bound to a project on its first workspace-touching action, which is the rest of omega#76's project-optional deliverable. Today it simply has no worktree: file mentions find nothing and a tool that needs a path fails the way it would in any worktree-less window. Thecmd-shift-abindings named in omega#76 are resolved rather than changed, and the resolution is now checked bythe_new_thread_chord_is_window_globalunderOMEGA-DELTA-0013: on macOS there is no editor-context collision to fix — upstream'seditor::SelectToBeginningOfLineis onctrl-shift-a, a different chord — and the only narrowercmd-shift-abindings are inside modal pickers (ToolchainSelector,RecentProjects) that fire while the user has opened them on purpose. On Linux and Windows the chord isctrl-shift-aand a terminal's select-all shadows it there, which is admitted for the same reason and enumerated rather than left to be discovered.
OMEGA-DELTA-0035 — The router is wired, and a pin is a gesture
- Upstream Zed: there is one agent connection per thread and no routing, so there is nothing to wire and nothing to pin.
- Omega, before this:
OMEGA-DELTA-0029built the routing law and the dispatch seam and wired neither. Nothing in the shipped app constructed anOmegaAgentConnection,observe_capacityhad no caller, and no surface could set a pin — so the route journal stayed empty and every thread disclosedroute: None. The exit properties held in the router and not in the product. - Omega now:
Agent::NativeAgent.server(..)returns anomega_router::OmegaRouterServer, whoseconnectbuilds anOmegaAgentConnectionover the native connection and publishes it. Every new first-party session is routed on purpose and its decision is written to the route journal before the turn exists. The agent panel polls the engine's framedget_capacityanswer on the same three-second cadence the Full Auto roster uses and hands it toobserve_capacity, so an engine-lane pin is decided against whatomega-effectdis actually doing rather than against a default of "not running". - A pin is a gesture, enforced by the argument type.
pin_session,unpin_sessionandpin_next_sessioneach require anomega_front_door::PinGesture, every variant of which is a control a person operates. There is noPinGesture::ToolCall, noSlashCommand, noRestoredDraftand noComposerMode, andpin_gestures_are_all_human_gesturesfails if one appears. This is the same construction owner gate 8 already uses forLaunchOrigin, applied at the pin because a pin is the only door to an engine lane and an engine lane is Full Auto authority. omega#76 rejected a composer mode flag for Full Auto because a boolean the send path reads can be set by a slash command, a restored draft, or a model-authored insertion; a pin stored as a mode would be the same construct wearing a different name. - Engine lanes are still reachable only through a pin. The unpinned default
is the native loop, always. Nothing here auto-prefers a ready lane, and
an_unpinned_thread_never_reaches_an_engine_laneincrates/omega_front_door/src/router.rsfails if the law changes. - A human pin re-decides; capacity moving does not. Setting or clearing a pin re-runs the decision for that session and records it, so an unhonourable pin appears on the thread's own line as a fallback with its typed reason instead of silently doing nothing. A later engine answer never re-decides a recorded session, so a turn does not move executors mid-thread because capacity changed.
- The thread carries the executor, not the router.
OmegaAgentConnection::new_sessiondelegates and returns what the executor built, soOMEGA-DELTA-0021's disclosure keeps classifying the executor. The two places that asked "is this the native agent?" by downcasting — the shared-project refusal and the native thread-store hand-off — go throughis_native_agent_servernow, because a wrapped native agent reading as external is a silently wrongfalserather than a compile error. - Enforced by:
the_router_is_wired_into_the_native_agent_entry,only_a_named_human_gesture_can_pin_an_executorandnothing_asks_for_the_native_agent_with_a_bare_downcastincrates/omega_deltas;pin_gestures_are_all_human_gesturesincrates/omega_front_door; the dispatch and journal suite incrates/agent_ui/src/omega_router.rs; and the rendered proofsomega_executor_disclosure_*andomega_route_pin_not_honouredincrates/zed/src/visual_test_runner.rs. - What this does not cover. No external ACP agent or engine-lane executor is
registered on the router in this build, so a pin to either fails closed to the
native loop with
external_acp_unavailableorengine_lane_not_connected— which is the honest answer and is what the rendered proof shows. The honoured pin the rendered proof shows is therefore a pin to the native loop, which is a real honoured pin (routed: pinned, notrouted: unpinned) but not an honoured engine-lane pin; that path is exercised only in tests. Turns still reach the executor through the thread's own connection rather than throughOmegaAgentConnection::prompt, because the thread carries the executor; the router decides per session, not per turn. And the pin menu is rendered on the thread's disclosure line, so a surface with no thread on it has no pin control.
OMEGA-DELTA-0036 — --uninstall removes Omega, and no part of anybody else
- Upstream Zed: ships
script/uninstall.shto remove a Zed installed byinstall.sh. Correct for Zed, and inherited wholesale by a fork. - Omega, before this:
crates/cli/src/main.rsembedded that file withinclude_bytes!and ran it, advertised in--helpas "Uninstall Omega from user system". It contained zero occurrences ofOmegaoromega. WithZED_CHANNELunset it removed/Applications/Zed.app, the whole~/Library/Application Support/Zedtree,~/Library/Logs/Zed, the caches, HTTP storage, preferences plist and saved application state underdev.zed.Zed, and~/.zed_server; it asked whether to keep "your Zed preferences"; and it printedZed has been uninstalled. It removed no Omega path at all — not the bundle, not~/Library/Application Support/Omega RC, not~/Library/Logs/omega-rc. A user who ran the advertised "Uninstall Omega" kept Omega and lost their other editor. This shipped in the signed, notarized0.2.0-rc13and0.2.0-rc14(omega#88). - Why nothing caught it. The paths lived in a hand-written table in a shell
script, disconnected from the code that creates those directories, so nothing
in the tree could observe that the two had never agreed. And
script/verify-omega-brandopenedContents/MacOS/omegaat three places andContents/MacOS/cliat none, althoughscript/bundle-omega-rccopies and signscliinto the bundle — the file the defect was in had never been opened by any check. That half isOMEGA-DELTA-0038. - Omega now: there is no path table.
crates/cli/src/uninstall.rsbuilds anUninstallRoots— one field per place Omega writes — where every field is read from thepaths::function that writes it:data_dir,config_dir,logs_dir,temp_dir,state_dir, the CLI symlink underpaths::BINARY_NAME, and the bundle-identifier paths fromrelease_channel::RELEASE_CHANNEL.app_id(). The app bundle comes from the bundle this CLI was launched out of, not from a literal.plandestructures the struct exhaustively, so a root added to it and left out of the plan does not compile. The script receives the plan inOMEGA_UNINSTALL_PATHS, one absolute path per line, and removes exactly those; unset or empty exits non-zero rather than falling back to a default, because every default this file has ever had belonged to somebody else's product./,/Applications,$HOMEand a relative path are refused before anything is removed. - Settings are asked for, never taken.
config_diris held out of the automatic list and prompted for by name, because it is the user'ssettings.jsonand keymap and the one root somebody may want to keep. - Enforced by:
the_uninstall_path_removes_omega_and_names_no_competitorincrates/omega_deltas/(the script names no other product; it still reads its plan from the caller;from_installed_pathsmakes at least onepaths::call per root;planstill destructures exhaustively; the script refuses an empty plan), and by three tests incrates/cli/src/uninstall.rs— includingthe_script_removes_omega_and_leaves_the_other_editor_untouched, which runs the shipped script against a fabricated home holding both an Omega installation and another product's, and reads both halves back afterwards. - Falsified. Adding a competitor's directory to the script failed the name
assertion. Removing
paths::logs_dir()from the plan failed both the plan test and the end-to-end test, which reads the roots rather than the plan precisely so a forgotten root cannot pass. Adding a hard-coded removal outside the plan failed the "left untouched" assertion byte-for-byte. Each falsification was probed against a pristine copy of the file before its test ran, so an edit that did not apply is a hard error rather than a green run. - Paid for once, in the worst way. The first falsification of this delta
restored the
0.2.0-rc14script over the rewritten one and ran the suite. The refusal test did not overrideHOMEat the time, the restored script ignores the plan entirely, and it destroyed the real machine's other editor and its application-support tree — the exact damage this entry describes. Every test in that module now runs with aHOMEof its own, whatever the script under it happens to be that minute.
OMEGA-DELTA-0037 — Omega identifies itself to third parties as Omega
- Upstream Zed: sends
HTTP-Referer: https://zed.devandX-Title: Zed Editoron every OpenRouter request. Correct for Zed. - Omega, before this: sent the same two headers, unchanged, on both the
streaming and the non-streaming call. OpenRouter displays the
X-Titlevalue to the account holder in their own dashboard, so this is not a wire contract that happens to carry a name — it is Omega telling a third party, and the user, that it is a different product. Every request through0.2.0-rc14did it, andstringson the shipped binary found exactly one occurrence, classified nowhere (omega#89). - Omega now: both call sites send
app_identity::PRODUCT_NAMEandapp_identity::PRODUCT_REPOSITORY_URL. The values come from the identity constants rather than from literals, so a rebase cannot restore the old value on one path and leave the other correct. - Enforced by:
outbound_attribution_names_omegaincrates/omega_deltas/, which asserts both request paths set the header, that neither literal is back, and that the count ofPRODUCT_NAMEuses equals the count ofX-Titleheaders. The pair is also recorded asblockedincrates/app_identity/fixtures/compatibility_allowlist.json. - Falsified. Restoring
"Zed Editor"on one of the two call sites failed the test; restoring it on both failed it; the packaged scan reports it out of the built binary independently.
OMEGA-DELTA-0038 — The packaged gate opens every executable that ships, and reads help as clap renders it
- Upstream Zed: has no equivalent; this is entirely about Omega's own gate.
- Omega, before this:
script/verify-omega-brand --appopenedContents/MacOS/omegaand nothing else.script/bundle-omega-rccopies and signs three binaries intoContents/MacOS—omega,cliandomega-identity-proof. Two of the three had never been opened by any check, which is why a destructive uninstaller (OMEGA-DELTA-0036) shipped in two published prereleases with the gate reporting green about the bundle. Separately, every prose stream inOMEGA-DELTA-0031reads source: a doc line, a literal, a schema comment. clap does not print source. It joins several doc lines into one sentence, resolvescfg_attrfor the platform it was built for, prints the flag name beside the description, and lays the whole thing out at run time. Nothing had ever read that output, so--zed <ZED>,Run zed in the foreground,Run zed in dev-server mode,Instructs zed to run as a dev serverand a--user-data-dirline naming a different product's data directory as Omega's own all shipped under a green gate (omega#89). - Omega now, three derived inventories where there were three lists:
- Every executable in the bundle.
bundle_executableswalks the app and keeps every file whose first four bytes are Mach-O magic. The icon-name rule, the embedded-asset rule, the prose scan and the first-party-agent scan all run over that set; only the two presence checks — the reviewed artwork and the required action labels — stay on the main binary, because only it embeds them. A helper added to the bundle tomorrow is inside the gate the day it is added. - Rendered output. Every executable is run with
--helpand--version, subcommands are enumerated from the help text itself rather than listed, and each is run in turn. Every line of the result is read as prose. The floor is on invocations read, not on findings. first_party_agent.phrases, applied to something.grep -c first_party_agent script/verify-omega-brandreturned 0: the key existed, a Rust test read it against the source tree, and no gate had ever applied it to a package. A reviewer had to run it by hand every time, which is the same as not having it. It now runs over every executable, with the identity string itself as the anti-vacuity guard.
- Every executable in the bundle.
- A classified sentence is matched as the compiler leaves it. Splitting
already handled
\continuations,\nand non-ASCII; a{}format placeholder is not in the binary either, because rustc splits a format string at every placeholder. Classified entries are now split there too — conservative in the same direction, since shorter fragments cover less, never more. - Enforced by:
the_packaged_gate_opens_every_shipped_executable_and_reads_rendered_helpincrates/omega_deltas/, which derives the shipped binary set by parsing whatscript/bundle-omega-rcwrites intoContents/MacOS, asserts the gate's floor covers it, asserts the gate names a binary path in exactly one place, and asserts each new check is both defined and called. - Falsified against a real candidate. The rewritten gate was run against the
installed, signed, notarized
0.2.0-rc15in/Applications, which the previous gate passed. It rejects it on 42 findings, including the uninstall script's text insideContents/MacOS/cli— a file the old gate never opened — and oncli --helpandomega --helpprinting three of the sentences above. The rebuiltclifrom this tree passes the same scan. Loweringminimum_executablesbelow what the bundler ships fails the delta test; deleting either new check's call fails it.
OMEGA-DELTA-0039 — The installed-proof harness observes what it records
- Upstream Zed: has no equivalent; this is Omega's own installed-candidate harness.
- Omega, before this: three checks in it could not fail, and a check that
cannot fail is worse than no check, because it produces a clean evidence table
(omega#90).
- The secret tripwire.
deliver_needle_through_protected_fdmade a pipe, wrote a freshsecrets.token_hex(32)into it, and closed both ends in the same function. No process was spawned;--appappeared only in the docstring. The needle had never been seen by anything but the script, which then searched the disk for it.status: "pass"was guaranteed by construction, whatever the product did. - Four of six surfaces watched directories Omega never writes.
logs,telemetry,crashesandclipboardresolved under~/Library/Application Support/Omega RC/…, whilepaths::logs_dir()is~/Library/Logs/omega-rcandpaths::crashes_dir()is~/Library/Logs/DiagnosticReports. The live 191 KB log was never opened. They recordedabsent, andabsentdid not fail the receipt. light-themeanddark-themewrotecontent_legible: Trueas a Python literal, with zeroocr_lines()calls and zerodiffering_pixels()calls, never comparing the light capture against the dark one. A frozen, blank or appearance-ignoring window passed both. This is the same shape as thedefaults readdefect5ce7f9855falready corrected forhigh-contrastandreduced-motion: a fact about the host filed as a fact about the product.
- The secret tripwire.
- Omega now:
- The needle is read from the caller through
--needle-fd— the canary the candidate was actually given — and a run without one refuses rather than inventing a secret nothing has seen. Before any surface is trusted, the same scanner is pointed at a needle planted in a private0600file; no match ends the run with no receipt. - Surfaces resolve from
crates/paths/src/paths.rs:logs_dir(), the telemetry log beside it,database_dir()plushang_traces_dir(), andcrashes_dir(). Clipboard and accessibility are read through their own interfaces — NSPasteboard (corroborated byclipboard info) and theAXUIElementtree of the running candidate — because neither was ever a file in a data directory. A surface that cannot be observed recordsblockedand the validator refuses the receipt, so "nothing was found there" and "nobody looked" no longer read the same. - The host appearance is only the precondition. Legibility is OCR'd off
each capture against a stated line count and confidence, and the light and
dark captures must differ by a stated pixel threshold. Every failure routes
to
blocked. script/bundle-omega-rcderived"dirty": Falsefrom nothing; it now readsgit status --porcelain, so a provenance field that reads like an observation is one.
- The needle is read from the caller through
- Enforced by:
the_installed_proof_harness_observes_what_it_recordsincrates/omega_deltas/, plus each collector's own--self-test. - Falsified. Breaking the needle comparison ended the run at exit 2 with no
receipt, where the old code would have written
"status": "pass". Repointing the surfaces back at the data root blocked the receipt and the untouched validator refused it; planting the needle in the real~/Library/Logs/omega-rcproducedstatus: failover 193,984 bytes, which the old table could not have seen. Four separate plants against the appearance block — an unconditional pass, a dropped pixel threshold, a removed pixel diff and fabricated OCR lines — each failed the self-test. Every falsification was probed against a pristine copy before its test ran.
OMEGA-DELTA-0040 — A first-ever launch lands on identity onboarding, and finishing it opens the front door
- Upstream Zed: first-run onboarding is a page you may open, skip, or close; nothing in the startup path waits for it, and the window opens regardless.
- Omega, before this: the ordering existed and nothing named it. Identity
onboarding gates startup (
await_identity_ready),OMEGA-DELTA-0019andOMEGA-DELTA-0034open the front door on a window with nothing to restore, and no test connected the two. A packaged first-ever launch therefore lands on Onboarding rather than the agent, which reads asOMEGA-DELTA-0034failing its own exit unless somebody decides on purpose that it does not. - The owner's decision, recorded rather than assumed. Omega is identity-first by design: omega#9's packet exists to put identity before editor setup, and an agent thread before an identity would invert it. "Fresh launch lands on the surface" is satisfied by the front door being the surface a usable session opens on. A genuinely first-ever launch legitimately lands on onboarding first, and every launch after it lands on the agent. The owner may veto this; it is written down so a veto has something to point at.
- The decision is only sound while the handoff is real, so the handoff is
the thing that is tested. "Onboarding first" and "onboarding instead" are the
same picture on a first launch and completely different products on the
second. Three links, each of which fails silently on its own:
restore_or_create_workspacewaits onawait_identity_readybefore it opens anything; the first-run branch ofon_finishcloses its own window and releases that wait; andrelease_identity_waiterscompletes the channel the startup path is parked on. Remove the middle link and setup completes into a launchpad that never becomes an agent — a failure no check on the front door alone can see. - Enforced by:
first_run_onboarding_hands_the_startup_off_to_the_front_doorincrates/omega_deltas, alongsidea_fresh_window_opens_on_the_agent(OMEGA-DELTA-0019) andthe_front_door_does_not_require_an_open_project(OMEGA-DELTA-0034). - What this does not cover. Abandoning onboarding is a dead end in that
launch. The first-run onboarding page is an ordinary closeable item; closing
it calls
Item::on_removed→onboarding_closed, which clears the "onboarding is open" flag and does not complete the startup channel. So a user who closes the tab instead of finishing setup keeps the launchpad window the onboarding page was hosted in, with the agent dock closed and no window ever created behind it. Identity is still not ready, so relaunching shows onboarding again and nothing is lost but the session — and refusing to continue without an identity is the identity-first posture working, not failing. Making the page unclosable, or making a close mean "quit", is an onboarding-surface decision (omega#9) and not this delta's to take. This delta also does not cover what onboarding asks for, or the editor-setup journey, which reaches the welcome page rather than the front door and is unchanged.
OMEGA-DELTA-0041 — Omega Agent is attachable over ACP, on a loopback socket that is off by default and read-only
- Upstream Zed: an ACP client only.
crates/agent_serversreaches out to external agents and everyConnectionTo<…>in the tree is aConnectionTo<Agent>. Nothing in upstream implements the agent role, so no external host can attach to the editor and use the agent it is configured with. - Omega: Omega Agent — the router, not a raw provider — can be served over
ACP to an external host on
127.0.0.1. An attaching host initialises, creates a session, prompts it, and is answered with the same disclosed routing an in-app thread carries. omega#82's recursive composability, in the direction upstream does not have. - Off by default, and that is asserted rather than intended.
OMEGA_ACP_SERVERmust be exactly1.true,yes,on,01,1and an unset variable are each off, with a typedOffReasonrather than a bool, andthe_served_acp_surface_is_off_unless_the_flag_is_exactfails on a truthy-tolerant read such asto_lowercase()orparse::<bool>(). A listener that is on by default is a different product. - Loopback by construction, not by configuration.
LoopbackHost::newrefuses anything but127.0.0.1and::1, and refuses a name rather than resolving it — resolution is the step at whichlocalhostcan be made to mean something routable.LoopbackAcpServer::bindtakes that type, so reaching a routable interface needs a new type rather than a new setting. - Read-only, inside the authority partition rather than beside it. This is
an unauthenticated model-driven surface —
authMethodsis empty, so it carries no bearer at all and is structurally weaker than the Desktop MCP surface. Owner gate 8 (no model-initiated path can start Full Auto authority; only an explicit human action can, wherever that action lives) therefore reaches it directly, and three model-callable Full Auto starts were removed from OpenAgents Desktop the same day. So the surface does not sit beside the partition:SERVED_SURFACEis the four methods a host can reach, every one of them observation, andUNEXPOSED_AUTHORITYclassifies every authority-bearing control with the typed refusal a host attempting it gets — checked in both directions againstFULL_AUTO_AFFORDANCESandPinGesture::all(), so adding a Full Auto control fails this crate's tests until somebody says what a served host is told. Anything not listed is refused by the absence of a dispatch entry, not by a branch someone has to remember. - A served session can never reach an engine lane. A pin is the only door to
one, setting a pin requires a
PinGesture, and no variant of that enum is reachable over a socket.a_served_session_can_never_reach_an_engine_laneproves the consequence against every engine state the router can be shown — including an engine with idle lanes and an executor registered — so "the engine happened to be down" is not what is doing the work. - Ingress is a record beside the disclosure, not a fourth executor class.
ExecutorClassanswers who ran the work; serving over ACP changes who asked. ReusingExternalAcpwould make a served session claim an external agent did work Omega did, and make one token mean opposite things depending on which side of the socket the reader stands on.OMEGA-AGENT-AC-04therefore stands unrevised at three classes andSessionOrigincarries the ingress. Both records cross the wire with exactly their declared fields —EXECUTOR_DISCLOSURE_FIELDSandSESSION_ORIGIN_FIELDS, asserted exactly rather than against a denylist, because a denylist that fails onlabelpasses forline,text,summary, andcaption. - GPUI never opens the socket.
crates/omega_acp_serverdeclares no dependency on GPUI,workspace,project,agent_ui, orui, and the only production caller ofstart_if_enablediscrates/omega_effectd— the supervisor layer. Both are checked by scanning the tree rather than asserted in prose. - Enforced by:
the_served_acp_surface_is_off_unless_the_flag_is_exact,only_the_supervisor_opens_the_served_acp_socket,nothing_over_the_served_acp_surface_can_take_a_pin,the_served_surface_presents_the_first_party_agent_id, andthe_supervisor_starts_the_served_surface_before_it_resolves_the_engineincrates/omega_deltas; the fourteen checks incrates/omega_acp_server, including one that drives the real loopback socket with the upstream ACP SDK client and reads the disclosure back off it; andthe_disclosure_record_holds_no_rendered_labelplusthe_origin_record_holds_no_rendered_labelincrates/omega_front_door. - A served prompt ends its turn, and says what it did not do. ACP has a
refusalstop reason and it is the wrong one: it means the prompt and everything after it will not be included in the next prompt, and stock Zed 1.12.0 implements that literally — it dropped the turn and showed a refusal banner with no disclosure at all. The turn genuinely ends, so it saysend_turn, and what did not happen is in the message the operator reads and in the typed record beside it. Both shapes are photographed rendering, in stock Zed 1.12.0 attached to this crate's socket, same build and same prompt, one value apart:crates/omega_acp_server/evidence/2026-07-26-zed-1.12.0-served-turn-end_turn.pngkeeps the turn and shows the executor and origin disclosure;…-served-turn-refusal.pngshows what the rejected shape cost — the turn gone from the thread and a bare "Request Refused" banner guessing at a content policy violation that never happened. A test assertingstopReason == "refusal"was green across that entire difference, which is why this bullet is answered with pixels and not with a passing assertion. - What this does not cover. The listener runs in the Omega process under the
supervisor's control, not inside the packaged
@openagentsinc/omega-effectddaemon; that daemon lives in the openagents repository and this packet is scoped to omega. What is enforced here is the property omega#82's falsifier names — the bind lives in a crate the UI layer cannot reach, and the start lives in the supervisor. The surface also does not execute: a served turn is answered by disclosing where it would route, and dispatching a served turn to a real executor is a later decision with its own authority question, not an omission. The v1 fleet-backed server (openagents #9179) stays deferred.
OMEGA-DELTA-0042 — Omega drives Exo as a lane, and supplies the authority gate Exo lacks
- Upstream Zed: external agents are attached over ACP or configured as custom agent servers. There is no notion of an executor whose own agent can rewrite itself, and nothing in the fork's ancestry has ever had to bound one.
- Which Exo, first. This is the maintained
OpenAgentsInc/exofork ofexoharness/exo, the recursive-self-improvement agent harness. Omega pins commitcd7c0d29db869e953fb7261d8390ca93007d36a6and treec61846e3f44daaf445930d1a499432ca9b069306. The fork contains the ACP transport while the upstream change is under review. It is not exo labs'exo-explore/exocluster-inference appliance, which shares a name and nothing else; omega#86 was closed for integrating the wrong one. The pin therefore carries the repository as a field a test reads, alongside the commit and the tree — both, for the same reasonomega-effectdis pinned by release tag and asset digest, because a commit id alone is satisfied by a rewritten history in a clone nobody re-fetched. Exo declares itself unstable with the written house rule "do not write fallback code or handle backwards compatibility." - What Omega is integrating, stated plainly. An unauthenticated local
harness whose agent has an unrestricted networked shell and can rebuild
itself. Exo has no approval prompt anywhere by design — its security model is
sandbox isolation, and its threat model assumes you want the agent to modify
itself. Omega adds the gate Exo does not have. The turn path runs these checks
before it sends. Each check uses a live observation:
- where Exo is —
EXO_EXOHARNESS_URLis inherited from the environment, and setting it redirects the lane from the state root on disk to an HTTP server that has no authentication and full access to Exo's secrets. It is parsed throughLoopbackEndpoint, whose only constructor refuses anything that is not this machine, and whose refusal separates0.0.0.0and::from loopback because those are the plausible mistakes; - which Exo —
gitin the checkout answers with a remote, a commit, and a tree, and the pin admits or refuses it; - which bytes — the binary is measured and compared against the owner's
omega_harnesspin ledger entry forexo, when the owner froze one; - which capability — Omega reads both
exo agent showandexo conversation show. The read includes exact tool-module paths, module digests, and agent-level and conversation-level mounts. The normal path refuses a self-modifying turn. A person can use a dedicated warning dialog to authorize one exact draft. The one-use grant binds the source commit and tree, binary digest, agent, conversation, connection generation, objective, capability set, tool-module digests, mount paths, turn reference, and expiry. Drift, reuse, restart, cancellation, and a different draft refuse. Networking is reported and is not refused.
- where Exo is —
- Prompts cross ACP, not command-line arguments. Omega starts
exo --root <root> acp <agent> <conversation>. ACP JSON-RPC carries the prompt on standard input. User text cannot become Exo argument syntax. - Omega never configures Exo. The admitted command starts
exo acpand reads capability records.create,update,delete,mount,set,register,configure,serve, andreplare unreachable. Exo owns its state and its durable turn log. - The executor class, decided rather than defaulted.
ExecutorClassis closed at three byOMEGA-AGENT-AC-04, and it answers who ran the work. An Exo thread reportsExternalAcp. NotNativeLoop, which is the first-party claim and would present an unrestricted shell's output as Omega's own. NotEngineLane, which is Full Auto authority — a record on it must carry arun_ref, and owner gate 8 admits only an explicit human action into it. Exo has no engine run and no receipt, so a lane reportingEngineLanewould be a fourth model-reachable door into Full Auto authority opened by adding an executor, three of which were removed from OpenAgents Desktop the same day.ExternalAcpfits because the class is about the executor and not the wire: a separate process Omega does not own, carrying no run reference. ACP does not change the class. A fourth variant was considered and not taken; the argument is written incrates/omega_exo_laneso a later reader can disagree with something concrete. - The disclosure names Exo, its executor, and its model —
external_acp · exo/basic · provider not disclosed/gpt-5-mini, from a real turn. No field was added toExecutorDisclosure: the record's field list is closed on purpose.provideris genuinely absent because Exo's LLM binding has no provider field at all, only an optional base URL, and saying "not disclosed" is better than derivingopenaifrom an absence. - The stream is typed. Exo maps each
ExecutionStreamEventto ACP. Omega receives live text chunks, tool calls, tool results, and a completion record. The completion metadata includes Exo's durable session, turn, and latest-event references. ACP cancellation uses cooperative executor cancellation. Exo appends a cancellation event and closes the durable turn before it reportsCancelled. - Turn-boundary behavior is explicit. Exo declares
CannotSteer. Omega queues a mid-turn prompt. It does not guess that Exo can steer, and it does not turn a steer request into an implicit cancellation. - Self-modification receipts are durable. Omega writes the one-use authority
decision and Exo's returned durable references to
exo-self-modification-receipts.jsonl. The thread shows the outcome, generation, and latest event reference. - Enforced by:
the_exo_lane_drives_the_harness_exo_and_not_the_cluster_one,the_exo_lane_puts_no_user_text_before_the_argument_terminator,the_exo_lane_exposes_no_endpoint_off_this_machine,the_exo_lane_opens_no_path_into_full_auto_authority,an_exo_turn_checks_the_pin_and_the_agent_before_it_sends,an_exo_turn_streams_cancels_and_requires_exact_one_use_authority, andthe_exo_lane_is_reachable_from_omega_agentincrates/omega_deltas/, the 40 unit checks incrates/omega_exo_lane/, anddrives_a_real_exoincrates/agent_ui/, which is#[ignore]d because it needs a real Exo. - Falsified against a running Exo, every edit probed before its run. Pointing
the checkout's remote at
exo-explore/exorefused the turn by name. Enablingtool_creationon the live agent refused it. Mounting Exo's own source treerwrefused it.EXO_EXOHARNESS_URL=http://100.64.7.9:4766refused it before any Exo process started. Dropping the argument terminator, making the turn reader accept any stdout, reportingEngineLane, unwiring the lane from the router, and moving the capability read after the send each failed their tests. One falsification found a real hole: removing the disclosure's Exo arm left the live test green, because it asserted only the agent id — which the fallback also produces. The live test now asserts the model, which only that arm supplies, and the same edit fails it. A second falsification silently no-opped through a shell quoting error and was caught by its probe rather than by its result. - What this does not cover. The grant does not give Exo Full Auto authority. Omega does not edit Exo configuration. Exo remains an external ACP executor and has no engine run reference.
OMEGA-DELTA-0043 — --uninstall removes the installation, not one file inside it
- Upstream Zed:
script/uninstall.shremoves/Applications/Zed.app— the bundle — along with the user-level directories. Correct for Zed. - Omega, before this:
OMEGA-DELTA-0036moved the path table out of the shell script and intoUninstallRoots, built from thepaths::functions that write those directories, and that fix is real: the plan derived by the signed0.2.0-rc16holds nine Omega paths and zero belonging to anybody else. Butcrates/cli/src/main.rshanded itapp.path(), which on macOS isOmega.app/Contents/MacOS/omega— one executable inside the bundle — into a field whose doc comment read "the application bundle or executable this CLI belongs to". So a full uninstall run against the signed0.2.0-rc16reported success and left/Applications/Omega.appstanding with 130.9 MB and five executables in it:cli, which still carries--uninstall,omega-identity-proof,omega-effectdand its bundled Node runtime. Zed was safe and Omega was not removed; the user was left to drag a signed, non-functional bundle out of/Applicationsby hand (omega#92). - Why nothing caught it. The end-to-end test planted the app root as a
directory holding a single marker file, and asserted the root was gone.
"Removed the bundle" and "removed the one file the plan named" are the same
observation from a root like that. And
InstalledApphad a singlepath()answering two different questions, shadowed on macOS by an inherentpath()that returned the bundle — so the same call spelled two ways returned two different paths, and the uninstaller took the wrong one. - Omega now:
InstalledApphas two methods with two names.path()is the executable to run;installation_root()is the whole directory a removal has to remove, and on macOS it is the.app. The ambiguous inherentpath()is gone, so there is one answer per question. The field isUninstallRoots::app_root, andfrom_installed_pathsruns whatever it is given throughuninstall::installation_root, which resolves any path under a.appto the outermost.app— a caller holding an executable, which every macOS caller does, cannot reintroduce the defect from outside. A loose development build with no bundle above it is returned unchanged, because inventing a root there would plan its parent directory for removal. - Enforced by:
the_uninstall_plan_names_the_installation_rootincrates/omega_deltas/(the derivation exists, the constructor normalizes through it, the call site asks for the installation, and the trait still distinguishes the two), and by two tests incrates/cli/src/uninstall.rs:the_plan_names_the_bundle_root_and_never_an_executable_inside_it, which asserts both directions — the bundle is planned, and no file inside it stands in for it — and the end-to-endthe_script_removes_omega_and_leaves_the_other_editor_untouched, whose fabricated bundle now holdsomega,cli,omega-identity-proof, theomega-effectdbundle and its Node runtime, every one of which is read back after the real script has run. The bundle path in that test is named independently of the plan, so a plan that names the executable plants its files somewhere else and fails rather than moving with the defect. - Proved against the product, not only the tests. The plan was derived by
running the built
cli --uninstallwithOMEGA_UNINSTALL_DRY_RUN=1under an isolatedHOMEagainst a fabricated bundle, exactly as omega#92 recorded the defect. Before:remove: …/Omega.app/Contents/MacOS/omega. After:remove: …/Omega.app, with the other eight roots unchanged. - Falsified. Reverting the call site to
app.path()reproduced the executable in the product's own dry-run plan and failed the delta test. Makinginstallation_rootreturn its argument unchanged failed the plan test and leftclialive in the end-to-end test. Both edits were probed in the file and in the rebuilt binary before their tests ran. - Handled with the care this path has earned. This is the code that
destroyed the owner's real Zed installation on 2026-07-25, when a
falsification restored the old script and one test did not override
HOME. Every manual exercise here ran withOMEGA_UNINSTALL_DRY_RUN=1and an isolatedHOME, against a fabricated bundle in a scratch directory. Nothing was ever run against/Applications.
OMEGA-DELTA-0044 — A brand-bearing command form is user-facing text
Upstream Zed: the CLI's interactive open-behavior prompt shows
zed --existing,zed --classicandzed <path>. Correct for Zed.Omega, before this: those three literals shipped verbatim in the signed
cliof0.2.0-rc16, inside a panel whose surrounding copy reads "Add to existing Omega window", "You can change this later in Omega settings" — naming our product twice and somebody else's binary three times.zed --existingandzed --classicare not Omega commands at all (omega#93).They are product claims by the gate's own rule.
OMEGA-DELTA-0031is written around one test: substitute our own name, and if the sentence stays true the brand was standing where our product's name belongs. "Add to existing Omega window (omega --existing)" is true of Omega. All three are rewrites, not classifications.Why the gate passed.
is_proserequires three tokens, so a two-token command form is invisible to it. That blind spot was known — the0.2.0-rc16release notes record "does not classify one- and two-word labels" — and this is it biting: the three literals were in neitherprose.classifiednor the compatibility allow-list, andverify-omega-brand --appexited 0.Omega now: the prompt builds every command form from
paths::BINARY_NAME, so it cannot drift from the binary it describes. And the blind spot is narrowed rather than papered over: the inventory admits prose or a command form — a brand word standing inargv[0]followed by flags, placeholders or paths — in all three streams (Rust literals, doc lines, embedded assets), on both the Python and the Rust side. Adding the three strings to a denylist instead would have reproduced exactly the defect the inverted inventory was built to end.The width was measured, not asserted. Across the whole tree the command-form shape adds 3 items — the three defects, and nothing else. Admitting any two-token literal beginning with a brand word instead adds 11 (8 more:
Zed Pro,Zed Agent,Zed AI,Zed Repository,Zed Twitter,Zed Default, andZed (Default)twice), all genuine references to somebody else's product that would need classifying. Admitting a bare brand token adds 58. A gate that cries wolf gets deleted, which is how a known blind spot stays open; the shape that costs nothing is the one that can be carried.Enforced by:
a_brand_bearing_command_form_is_user_facing_textincrates/omega_deltas/(the three shipped literals are invisible tois_proseand visible tois_command_form; the eight two-word labels and a bare brand token are not command forms; andscript/verify-omega-brandcarries the same rule wired into the same three streams, so the source and packaged sides cannot drift), andthe_cli_prompt_names_our_own_binary, which readsprompt_open_behaviorand fails on any brand hit or on a command form not built frompaths::BINARY_NAME.Reachability, and what was actually observed.
resolve_open_behaviorincrates/zed/src/zed/open_listener.rssendsCliResponse::PromptOpenBehaviorwhen there are existing windows, the paths are not already in a workspace, at least one path is a directory, and the settings file has nocli_default_open_behavior. omega#93 recorded a shipped-string result, because the reporting lane could not get the installed CLI to render the panel with all four conditions held. This lane rendered it: the builtcliwas run under a pty against a stand-in for the editor that performs the real IPC handshake and sendsPromptOpenBehavior, and the panel came up readingConfigure default behavior for omega <path> You can change this later in Omega settings: > Add to existing Omega window (omega --existing) Open a new window (omega --classic)So the CLI half is live code, not dead code, and the copy it renders is ours. What that does not establish is that a running Omega reaches the four send conditions in practice — the stand-in supplied the response. That half is still unobserved, and the panel is still worth deleting if nobody can make a real Omega send it.
Falsified. Restoring
zed --existingfailed both the prompt test and the unclassified-prose test. Restoring the three-token rule alone — leaving the literals fixed — failed the command-form test. Removing the rule fromscript/verify-omega-brandwhile keeping it in Rust failed the parity assertion. Each edit was probed in the file before its test ran.
OMEGA-DELTA-0045 — A provider handoff is visible in the thread the owner reads
- Upstream Zed:
AgentThreadEntryhas six variants — a user message, an assistant message, a tool call, an elicitation, a completed plan, a context compaction. Every one of them is something a model or a user said. Correct for Zed, which has no supervising host writing into a thread. - Omega, before this: Omega does have one.
omega-effectdmoves a Full Auto run from one provider lane to another and emits a note naming both lanes, addressed to the target thread. The host method it calls,omega_host_bridge::append_system_note, validated its parameters and then answeredunavailable("Agent threads do not expose an owner-visible system-note authority.")— because there was no entry kind a non-model disclosure could be, so there was nowhere to put one. - Why that is a defect and not a limitation.
0.2.0-rc11shipped a handoff that changed which model was spending the owner's budget and left nothing in the transcript the owner reads. The refusal is an improvement on rc11's silent() => {}— it is typed, it is honest, and an operator reading the wire can see the disclosure was dropped — but the owner reading the thread cannot, and the owner reading the thread is the person the disclosure is for. An independent reviewer confirmed the refusal string is in the shipped bytes of0.2.0-rc15and0.2.0-rc16; it is inrc17too. No candidate to date discloses a cross-provider handoff in the thread. - Omega now: a seventh variant,
AgentThreadEntry::SystemNote, carrying an engine-supplied id and plain text;AcpThread::push_system_note, idempotent on that id; andThreadView::render_system_note, which draws it as a captioned rule in the transcript — the same shape the thread already uses for "Subagent Output".append_system_noteresolves the thread named bythreadRefand appends. - Three properties the shape is chosen for.
- Unconditional. No collapse, no expansion toggle, no hover. The gate is owner visibility; anything the owner has to click to see is a disclosure the rc11 handoff would also have passed.
- Not Markdown. The text is a
SharedStringthe host wrote, drawn as aLabel. Nothing a provider emits can style one of these lines or pass itself off as one. - Idempotent on the engine's id, not last-write-wins. The engine may retry after a response it never saw. A retry must not be able to rewrite a disclosure the owner has already read, and must not double it either. The idempotence is per live thread, which is the scope that matters: the note is an entry in the thread, and a thread that is gone has no owner reading it.
- The cost, stated. This is a variant added to
crates/acp_thread, a shared upstream crate, so it is a real rebase surface — unlikeOMEGA-DELTA-0021, which deliberately kept the executor record out of that crate behind an extension trait. An extension trait cannot add an enum variant, and an out-of-band side table keyed by entry index would not survive reordering, would not appear in the thread's Markdown export, and would put the disclosure somewhere other than where the transcript is read. The variant is the seam; the rebase cost is accepted deliberately. - Enforced by:
a_host_authored_note_is_a_thread_entry_kind,the_host_appends_a_provider_handoff_note_rather_than_refusing_it, andthe_thread_surface_draws_a_host_authored_note_unconditionallyincrates/omega_deltas/. The three halves are separable and each one alone is passable and useless: a variant nothing renders discloses nothing, a renderer nothing dispatches to discloses nothing, and a host method that returns{"appended": true}without writing anything is a refusal that lies rather than a refusal that is honest. - Scope. This is the source half.
0.2.0-rc17and every earlier candidate carry the refusal in their shipped bytes; the packaged half needs the next candidate.
OMEGA-DELTA-0046 — Exo threads have a native conversation workspace
- Before this change: An Exo thread used the standard transcript and composer, but its Exo-specific interface was one compressed disclosure row. The row did not show the observed harness state, the current turn state, or the exact authority boundary. A user could not inspect the Exo lane as one coherent system.
- Omega now: An Exo thread has a dedicated workspace header and runtime inspector. The transcript and composer remain the standard Omega components. Text, tool calls, tool results, errors, completion, queued prompts, and cancellation therefore keep one rendering and control path.
- The inspector is a projection, not a second source of truth. It reads the exact observation that gates each turn. It shows the agent, conversation, executor, model, provider disclosure, ACP transport, turn state, source pin, binary digest, tool modules and digests, writable mounts, network state, and the last one-turn authority receipt. Each terminal turn also shows the durable Exo session, turn, and latest event references that Exo returned, whether or not that turn needed self-modification authority. If observation fails, the inspector reports that failure and does not invent runtime facts.
- The controls use existing authority. Refresh runs the read-only Exo observation. Stop uses the existing ACP cancellation path. The one-turn self-modification control appears only when the observed capability set needs it, and it uses the existing exact-draft confirmation and receipt path. Omega does not add an Exo configuration command, listener, proxy, or Full Auto route.
- The layout is responsive and native. A wide window puts the inspector beside the transcript. A narrow window puts a bounded inspector above it. The interface uses the active Omega theme tokens and standard controls. It does not add a separate dark theme or a web surface.
- Enforced by:
an_exo_thread_has_a_live_workspace_and_exact_runtime_inspectorincrates/omega_deltas/, the Exo inspection and turn-state tests incrates/agent_ui/, the real Exo acceptance pathdrives_a_real_exo, andomega_exo_workspace_wideplusomega_exo_workspace_narrowin the native Metal visual runner. The visual path starts the shipped ACP transport, sends one real turn, requires the reply and all three durable references, and then records both layouts.