Skip to content

Releases: Maurdekye/orgtree

Orgtree 2.1.9

Choose a tag to compare

@Maurdekye Maurdekye released this 20 Sep 14:09

Orgtree 2.1.9

This release is about the interface staying usable while agents actually work.
On a large organization, reading anything used to cost as much as reading
everything, every write stood in one queue behind every other write, and the
person watching paid for it: inboxes that timed out, saves that took ten
seconds, halts that took a minute. 2.1.9 reworks how organization state is
read and written, then stabilizes the management operations around it.

It arrives through four betas — beta.0 through beta.3 — that were each
measured against a copy of the real organization that surfaced the problem,
and then validated live. This stable build is byte-for-byte the proven beta.3
contents; only the version and these notes differ.

Upgrading

The tray's Update now will offer this build to an existing installation.
Existing betas on the 2.1.9 line update to it as well.

Reading one thing no longer costs reading everything

Every read of the organization used to build the entire organization in
memory first. Every write did that twice — parsed everything to change one
field, then re-serialized everything to work out what changed — and every
write in the whole program queued behind a single lock while it did. On a
101 MB organization that meant roughly eleven megabytes parsed and eleven
re-serialized for a six-kilobyte change.

Now a read costs what it reads, a write re-serializes only what it touched,
and the document stays resident between writes instead of being rebuilt each
time. The organization tree no longer re-parses the document at all: it
rebuilds from a shared snapshot refreshed by exactly what each save changed,
and a rebuild parses zero bytes of it (a test counts).

The interface converges by arithmetic instead of refetching: every update the
server pushes carries a sequence number, every full tree states which updates
it already includes, and a gap in the numbers triggers exactly one catch-up
fetch.

Measured live on this organization, under an eight-agent working load,
against the same operations on 2.1.8-era builds: common reads three to four
times faster (p50 roughly 350–470 ms against 1.5 s), agent status writes
eighteen times faster (p50 124 ms against 2.3 s, worst case 1.5 s against
14 s), and about 1,300 consecutive live calls with zero failures. Uncontended,
a tree read costs about 2 ms and an ordinary write about 11 ms.

Halting or resuming a group is one operation

Halt and unhalt accept a list of agents: one permission check, every target's
process interrupted up front so they terminate in parallel, and per-agent
results. A halt that used to take 66 seconds for a wave of agents takes about
three. Halting an agent is also now a confirmed kill — the operation reports
when the process is actually gone, not merely asked to leave.

Changing a busy agent's account now queues

Changing the account or model of an agent that is mid-turn no longer fails or
tangles with a queued model switch. The requests queue per agent, apply in
acceptance order at the turn boundary, compose correctly with a queued switch
(including across providers), and an agent whose account change lands while
it is frozen on an exhausted account is woken exactly once. This area
received four review rounds and a 39-test reliability suite before landing.

Management fixes from across the beta line

  • The whole interface no longer freezes while one agent is being managed,
    and a restart no longer strands agents it never got round to.
  • A window that loses the engine comes back by itself, and the window
    controls stay visible on error and holding screens, so a stranded view can
    always be closed, minimized, or refreshed. Refreshing a stranded view
    restarts Orgtree cleanly instead of silently doing nothing.
  • Quick Staffing can suggest an account for the requested tier when the
    option is switched on (it is off by default); the receiving agent keeps its
    staffing authority and the suggestion is carried, not imposed.
  • Attention flags behave like records: an agent can take back its own
    flag without destroying the ticket, answering a flag no longer deletes the
    question, and an unrelated edit no longer takes down a flag the user is
    still reading.
  • Ticket descriptions no longer get corrupted, and reassigning a ticket
    no longer starts work that was left deliberately unstarted.
  • The full agent menu is available from every view, the message box
    remembers what you sent, and right-click works in text fields.
  • Codex CLI can run against OpenRouter as a backend.
  • Every slow request explains itself: any request over half a second
    leaves a durable trace with a stage breakdown and an explicit unattributed
    remainder, so a slow moment can be diagnosed from the build itself.

What still is not fast

Honesty about the remainder: under heavy many-agent load, the full
organization view and some saves can still take multiple seconds — the
residual cost sits in building and serializing the full tree, not in the
storage fixes above. That remainder is measured, traced, and is the subject
of a full state-system rearchitecture currently in design. It ships when it
is proven, not before.

The numbers, and how to read them

The headline figures above were measured live on the organization that
surfaced the problem, under a real working load, and the earlier bench
figures they confirmed were measured against a 101 MB copy through the real
API. They are strong evidence, not a guarantee for every organization shape;
the slow-request tracing in this build is the instrument that decides any
disagreement.

Orgtree 2.1.8

Choose a tag to compare

@Maurdekye Maurdekye released this 18 Sep 11:05

Orgtree 2.1.8

Most of this release is about agents that stop working and nobody finding out.
An agent could sit frozen for a day on a quota message that had stopped being
true; when an agent did stop, the person or agent responsible for it was told in
a way that never actually reached them; and the countdown meant to say when it
would resume reached zero early and then sat there.

The rest is the composer, the tray, and a set of tooltips that had grown into
paragraphs.

Upgrading

The tray's Update now will offer this build to an existing installation.

An out-of-date quota message no longer freezes an agent

An agent could sit frozen for hours on a quota error that had stopped being true
long before. The account had capacity, the credentials were fine, and other
agents on the same provider were working — but the coding tool kept returning
the same refusal, word for word, with the same countdown, for more than twenty
hours. Ten consecutive attempts received an identical message, including two
only seven minutes apart that both claimed the same time remaining. A countdown
that never counts down is not a live measurement, and the agent was being held
by an echo.

Orgtree already had a guard for exactly this: when a quota error arrives, check
it against the coding tool's own conversation history and cancel the freeze if
the error is historical rather than current.

That guard had never once run. It refused to read the conversation database
whenever a temporary sidecar file sat beside it — and the coding tool keeps that
sidecar open for the whole duration of a turn, which is precisely when the guard
is asked to run. Over six days it declined 108 times out of 108 and corrected
nothing. The code had no test coverage at all, which is how a safety net that
never caught anything stayed invisible.

The sidecar now chooses how to read rather than forbidding the read. With no
sidecar, the database is opened exactly as before. With one, it is opened
read-only in a single transaction, so every query sees one consistent committed
snapshot of a database another process is actively writing. Nothing is ever
written, and a database that cannot be read coherently still declines rather
than guessing — a failed read never invents a correction, so an agent that
genuinely should stay frozen does.

Detecting a real limit is untouched. An agent that hits a current wall still
freezes, and nothing runs past a live limit. What changed is only whether a
stale message counts as a live one.

This has since been confirmed on a live agent rather than only in tests. An
agent that had been re-freezing every five minutes for twenty-two hours was
released within four minutes of the fix going live, and completed a normal turn.

An agent whose work stops now gets someone's attention

When an agent hit a provider usage limit, the agent responsible for it was told
by a message that did not wake them. They found out whenever they next happened
to run for some other reason — which could be hours, or never.

Two notifications were wrong this way: hitting a usage limit, and being parked
indefinitely. Both now wake the manager. The other three notifications in the
same family already did, and were left alone; being noisier was not the goal.
The existing limits on how often this can fire are kept, and one more was added,
so an agent that keeps hitting the same wall cannot wake its manager over and
over.

For a top-level agent the manager is you, and that notification was arriving
in your inbox already marked read — no unread badge, nothing to draw your eye.
You found out when you happened to look, which is the same failure the change
above exists to prevent. Those notifications now arrive unread. They do not
pulse your inbox; that signal is reserved for something genuinely needing you
immediately, and it only keeps working while it stays rare. Three purely
informational notifications were checked and deliberately left as they were.

A released freeze no longer forgets what it was waiting for

When an agent's usage-limit freeze expired, the record of the wall it had hit
was deleted. If the agent then ran and hit the same wall moments later, nothing
was left to compare against, so a restated limit was treated as brand new and
the agent was frozen for the full period all over again. Worse, the recovery
path — the one that exists precisely to release an agent held on a stale
deadline — depended on evidence that this deletion had just destroyed, so it
could never run.

The wall's evidence now survives the release that clears the freeze, and is
forgotten when a turn genuinely completes, since a turn that ran means the limit
is no longer in force.

The usage-limit countdown no longer reaches zero early

A frozen agent's countdown hit zero roughly a minute before the agent was
actually allowed to wake. The freeze was never stuck — the wake adds a short
grace period the displayed number did not account for, so the badge sat at zero
while nothing appeared to happen.

The badge now counts down twice, in sequence: first to the reset time the
provider itself stated, then a second short countdown to the moment the agent
can actually resume. Two honest numbers rather than one number quietly carrying
an allowance it never mentioned. The wake fires at exactly the same instant it
always did.

Agents can move a stuck agent to an account with capacity

You have always been able to move a frozen agent onto a different provider
account and release it in one step. Agents managing other agents could not: the
two operations available to them refused each other, and releasing the freeze
without moving the account simply re-froze it seconds later on the same
exhausted account.

They now have the same single operation, and it runs the exact same code yours
does, so the two cannot drift apart. It checks that the destination account
actually has capacity first and refuses if it does not, rather than moving a
stuck agent somewhere equally stuck.

Restart engine is always in the tray menu

The tray's Restart engine row used to appear only when the engine was
stopped or unavailable — so it could not be found in the ordinary case of a
healthy, running engine, which is the case you usually want it in.

The row is now present in every state and can be clicked while the engine is
running. It greys out only when a restart genuinely cannot be performed: during
startup, during a quit, while an update is installing, and while a restart is
already in flight.

Worth knowing before you use it: restarting a running engine ends the current
turn of every live agent, and that cannot be undone. There is deliberately no
confirmation prompt.

The notice toggle is in every reply box

A notice is a message that lands in the recipient's mailbox and is read when
they next run, instead of waking them for it — the right shape for a heads-up
worth knowing but not worth interrupting anyone over.

That toggle now exists in the ticket reply, the mail reply and the presentation
reply as well as the main composer, and works the same way in all of them: it
sits above the attach button, Alt+N toggles it, a send that cannot be
delivered as a notice falls back to ordinary mail rather than failing, and a
sent notice is drawn with a dotted border. Each box remembers its own setting
and starts switched off; arming one does not arm another, and it disarms itself
once the message is sent.

The org-inbox compose modal is the one deliberate exception. It addresses
parties outside this organization, and a notice to an outside address is refused
by the server regardless — a control that could never do anything there would be
worse than no control.

When the composer is in notice mode its dashed edge follows the current
provider's colour, matching the edge that notice messages themselves wear.

Smaller interface fixes

The message box types from the top. Text started part way down the box,
leaving a blank gap above the first line. The text area now sits at the top and
grows downward, so typing begins at the top whether the box is empty or already
expanded. The attach, notice and send buttons have not moved.

One attachment icon everywhere. The file-attachment button did not use the
same picture in every place you can attach a file, so the same action looked
like a different feature depending on which box you were in. Every attachment
control is now a paperclip, including the docket item's, which was text only.

The attach button works in mail replies. It was visible but permanently
greyed out, so a reply could not carry a file. The reply box enables attaching
only when it knows which organization the mail belongs to, and the one place
that renders a mail reply was not passing that along.

The toolbar organization list draws one highlight per row. Highlighting a
row split it into two blocks with a visible seam, which read as a rendering
fault — the highlight was painted on each cell rather than on the row. Each row
is now a single box with one wide rounded highlight across it.

Tooltips that said too much

Three hovers had grown into panels and are now ordinary one-line tooltips.

The account badge showed six lines listing the account, provider, label,
email, sign-in state and standing. It now shows the account id and the email.

The cache badge could run to ten lines of explanation. It is now one short
line: a brief reason when the cache is not ready, or a simple confirmation with
a few words of context when it is.

The MCP tool count chip showed four lines — the current count, the count
from the last turn, which provider and code path produced the reading, and the
readiness state. It now reads 3 callable MCP tools, with the readiness state
as a short trailing clause when there is one. The count line only repeated the
number printed on the chip an inch away.

In all three cases the badge itself — its symbol, its colour, its cou...

Read more

Orgtree 2.1.7

Choose a tag to compare

@Maurdekye Maurdekye released this 17 Sep 13:35

Orgtree 2.1.7

Almost all of this release is about the machinery agents work through rather
than the screen you look at: the docket, the work-item tools, git worktrees,
usage limits, and the test suite. Nearly every fix in it came out of an agent
describing what got in its way while it was trying to do something else.

Three are worth reading even if you skip the rest. A test run could pass against
code it was not testing. Removing a git worktree could delete the repository it
was linked to. And a work item could be completed with nothing checked at all.

Two changes are visible in the interface: a toggle beside the composer that
sends your next message as a passive notice, and switching a live agent's model,
provider or account, which no longer strands the agent it was switching.

Upgrading

The tray's Update now will offer this build to an existing installation.

Send your next message as a passive notice

There is now a toggle beside the message composer. With it on, your next message
to an agent is delivered as a passive notice: it lands in that agent's mailbox
and is read at its next turn instead of waking it immediately. The composer
takes on the same soft dashed edge that notice messages wear, so the mode is
visible before you press send rather than after.

This is the thing you want for an FYI. Telling an agent "nice work" used to cost
it a full turn to receive and another to be polite back.

Alt+N toggles it. It disarms when you send and at no other time — not when you
press Escape, not when you clear the text, not when you switch recipient. If the
recipient cannot take a notice, the message is sent as an ordinary one rather
than failing. In the transcript, only messages actually delivered as a notice
carry the notice edge.

Switching a live agent's model, provider or account is reliable

Rebinding a running agent had six separate defects, all of them fixed:

  • A rebind issued while the agent was frozen by a usage limit is now refused
    outright, instead of leaving the agent stranded between two seats.
  • An authentication freeze now thaws on the switch rather than surviving it.
  • A rebind is guarded while work is genuinely in flight.
  • The switch is announced, so a message dropped at the boundary is reported
    instead of vanishing quietly.
  • A replay that crosses a thaw survives it, and the continuity narration says
    honestly what was and was not carried over.
  • The rebind goes through a single writer, which is what made the previous five
    reproducible in the first place.

Usage limits no longer strand an agent

Two faults with one visible symptom. An agent that hit a Claude session limit
had its turn ended outright instead of being frozen until the limit lifted,
because the step that records the limit could fail in a packaged build and take
the freeze with it. Separately, an agent frozen on a Gemini limit could stay
frozen indefinitely: each check re-read the same fixed countdown and pushed the
release time further out, so the deadline moved away as fast as the clock
approached it.

Both are fixed. A limited agent freezes and recovers on its own.

The reserve badge on an agent now appears only when that agent is actually
running on reserve capacity, rather than whenever it was the kind of agent that
could be. When the lane cannot be determined it shows nothing instead of
guessing.

A test run could pass without testing your code

On a machine with Orgtree installed, a test run started the ordinary way could
import the installed application instead of the working copy. It failed in both
directions and said nothing about either: a run could fail on code you had never
written, or — much worse — pass on shipped code that did not contain your change
at all. Nothing in the output distinguished the two.

The cause was Orgtree's own doing. It puts the installed application on the
import path when it starts an agent, which that agent needs in order to run at
all, and every command that agent starts inherits it.

Test modules now check where they imported the application from. If it came from
outside the working copy they stop immediately and say so, naming the path they
actually loaded, the copy they expected, and the exact command to run instead.
They refuse rather than quietly correcting the path, because a run repaired into
looking trustworthy is the same problem one step further along.

Removing a worktree could delete the repository

A git worktree whose dependencies were linked back to the main checkout could
take that checkout with it when removed. This was already known for forced
removals; it turns out an ordinary removal does exactly the same thing, and an
ordinary removal is what people actually run, because the link leaves the
worktree looking clean.

Worktree removal now refuses whenever a link leaves the worktree, forced or not,
and names the way to clean it up safely. There is also a scan-and-clean command
for links that already exist, because refusing a removal does not disarm the
ones already on disk.

A work item could be completed with nothing checked

Completing an item recorded the completion whether or not its acceptance
conditions had been checked, so an item could reach Done carrying no evidence at
all and read exactly like one that had been verified. The gate now records an
unclassified completion instead of letting it pass silently, and the invariants
are pinned so no later ruling can quietly relax them.

The docket

A finished item can record what happened after it finished. Marking an item
done used to lock it, so the commit that actually landed afterwards had nowhere
to go. A new addendum action amends a completed item without falsifying its
completion or wiping its acceptance record.

Approving a review no longer closes the ticket before the code lands. There
is a third review outcome, approve_stage, that accepts the work without
completing the item — the state you want between "this is right" and "this is on
main".

An owner can ask for a peer as reviewer. Review used to be reachable only
upward, which meant a coordinator reviewed everything or nothing did. An owner
now requests the review seat, and the request is routed to the nearest agent
with the standing to grant it.

Agents listed on an item can read its previous holders' work. When an item
changes hands, the new holder can read the scratch and transcript of the agents
who held it before — scoped to that item, not a general grant.

Amending acceptance conditions works. It used to be accepted and silently
discarded. Conditions are now written and versioned, and any condition whose
wording changed has its recorded evidence cleared, since that evidence was
gathered for different words.

Two actions now really do compare-and-set. check and accept are the
actions that mutate the record deciding whether an item is complete, and they
were taking the "only if unchanged" argument and ignoring it. Both honour it
now, refusing before anything is written and naming both revisions.

Arguments that do nothing are refused rather than dropped. An action that
does not read an argument now says so instead of accepting the call, advancing
the revision and quietly discarding it. The agents who followed the
documentation are the ones who were affected, which is why this is a refusal and
not a silent correction.

Nothing is silently cut. Every bounded field was audited against what it
actually promises. Over-length input is refused with the submitted length, the
limit and the overage, rather than being quietly shortened, and the fields whose
briefs ask for several substantive things were given room to hold them. The
dismissed-attention reason was being dropped entirely; it is kept.

get and list return payloads you can actually read. Both grew a compact
projection, and the docket stopped serving its own record twice inside the same
response.

Smaller tool corrections. update no longer demands both progress lists
when you are only appending to one, and keep_done composes with done_append
instead of conflicting with it. check and evidence report every validation
fault in a batch at once instead of one per round trip. A fields caller can
ask for ref by name.

The landing slot on main is a mechanism. Coordinating who merges next used
to be a convention passed around in mail. It is a lease now.

Worktrees, permissions and the test suite

Worktrees work out of the box. Creating one needed a separate elevated write
to .git, which agents discovered by hitting the wall rather than by being told
about it. The wall is named up front now, a helper does the elevated step, and
the helper is deliberately hard to mistake for a way around the denial.

The sensitive-path gate says what it is. The refusal named a single
directory; the gate actually covers nine, and it sits above the permission
system, where a headless turn has nobody available to answer the approval it
raises. Agents are now told this before they meet it, including what does and
does not clear it.

An agent's own scratch folder is writable. The read-only carve was denying
agents write access to their own working folder.

The suite passes inside a worktree. engine/runtime is located by searching
upward, which restores ten tests that had been silently skipping in every
worktree.

One renderer test run no longer balloons esbuild to 8–9 GB. The bundle step
is batched and the esbuild service is stopped afterwards. The run costs about
eight seconds more when warm.

A tripped run limit is loud. This one is worth reading twice. If the renderer
suite hit its run limit, whole batches of test files were dropped — and the
batches that had already finished left a "0 failures" summary on screen. A run
that never tested half its files was indistinguishable from a clean one. The
runner names both numbers now: RUN INCOMPLETE: 175 of 234 test files never ran to completion. ...

Read more

Orgtree 2.1.6

Choose a tag to compare

@Maurdekye Maurdekye released this 16 Sep 15:56

Orgtree 2.1.6

The stable release of the 2.1.6 line. It is a large one: the mail hub that lets
organizations reach each other has become its own product, promoting an agent
now carries its whole team with it, mail says what actually happened to it, the
renderer keeps up with a busy organization instead of falling behind it, and a
window that dies now comes back by itself.

Alongside those, this release fixes the faults that made the previous version
tiring to use: a crash when expanding a question answer, an installer that
refused an upgrade and blamed unrelated programs, agents whose conversation file
had moved and could not be woken, an answered question card that reappeared
after a restart, and a work item description that could freeze the panel it was
in. The rest is interface work — the agent desk's panels, the docket's sections,
and the badges on the chart.

Upgrading an existing installation

The tray's Update now offers this release to any 2.1.5 or later
installation, and installations already on the beta line receive it the same
way. Nothing needs to be installed by hand.

Mail hub startup

The packaged embedded Python runtime did not name the hub's own directory on its
import path, so the mail hub could not start in an installed build — the
embedded interpreter reads its search path from a ._pth file and ignores
PYTHONPATH entirely, which is exactly the case the layout checks did not
cover. The path file now names the hub directory, and the packaging checks fail
closed rather than producing a build whose hub cannot start.

The mail hub is now its own product

The mail hub that lets organizations reach each other has been taken out of
Orgtree and pinned as a separate repository, orgtree-mailhub. Orgtree tracks
an exact commit of it rather than carrying its own copy, so the hub can be
fixed and released on its own schedule without a desktop release.

Every hub-facing surface in the interface has been rebuilt on the hub's own
model rather than on the shape the old built-in hub happened to have.

Promoting an agent moves its whole team

Self-subjugation — inserting an agent above another — is now a single atomic
subtree promotion. The promoted agent takes its position with its entire team
underneath it, and the move either happens completely or not at all.

A promotion also keeps both team charters instead of dropping one of them. The
standing instructions the promoted agent gave its own team, and the ones it now
inherits, both survive the move.

Mail tells you what actually happened

When mail is addressed to a node that cannot receive it, the sender is now told
what really happened rather than being left to infer it from silence.

Questions and the docket

  • Question cards are rendered as sanitized Markdown, so a question written with
    headings, lists or code in it reads as intended instead of as raw text. The
    same rendering covers option labels and descriptions.
  • Long docket tickets collapse their detail sections, so a ticket with a large
    description no longer pushes everything else off the panel.
  • The attention dismiss control now sits beside the attention block it applies
    to, rather than somewhere the block does not explain.
  • Staffing an item with Quick Staff notifies the agent that previously held it,
    and only when the staffing actually succeeded.
  • A question attached to a docket item raises one notification instead of
    several.

Interface

  • A collapsed hire's expanded token list draws in the right layer instead of
    behind what it should sit above.
  • Narrow modal lists collapse into overlay panels rather than being squeezed
    into a column too narrow to read.
  • The unhovered model icon at far zoom is larger and better spaced.
  • The tray offers a Restart engine entry when the engine has stopped, so a
    stopped engine can be brought back without restarting the application.

Stability

  • The fold store no longer loops forever. Its sweep removed keys after every
    render while the fold effect added them back on every store change, and a
    fold whose key set only partly matched the census could keep the two fighting
    until React gave up — an infinite re-render that took the interface down. The
    two halves now settle instead of undoing each other.
  • The docket description compares a fold measurement before storing it, in one
    place shared by both surfaces that measure folds. Writing an unchanged
    measurement back from a resize observer is the same feedback loop by another
    route, and only one of the two surfaces was guarding against it.

Automatic compaction

Automatic cache-protective compaction was refusing to run for exactly the
agents it exists for. It consulted the agent's own last reported status and
skipped anything that had said it was blocked — but at the point the decision
is made, that status is always the previous turn's report, because the
current turn has not replaced it yet. An agent that asked a question, reported
blocked, went quiet past its cache lifetime and then woke on the answer was
never compacted.

The decision is now made on the session rather than on a status word.

A question an agent has asked you also survives being compacted. Compaction
used to discard the agent's open request, which meant a question could vanish
off your screen without you or the agent closing it; the question now carries
across to the replacement session, and the replacement is told it inherited
one. Answering still wakes the agent and still lets it compact.

Expanding a question answer no longer kills the desk

Clicking a question answer in an agent's chat transcript could take the whole
desk down instantly — a blank error boundary where the conversation was. It
happened only when that agent was working at the time, which is why it
looked random.

The transcript re-measures its own layout after every render, and that
measurement almost always comes back the same. It was written to skip the
update when the value had not changed, and that is where the mistake was:
skipping the change stops the redraw, but the update is still handed to React,
and React only discards it when the component has nothing else in flight. A
streaming agent always has something in flight. So the measurement scheduled a
render, the render re-took the measurement, and the two fed each other until
React gave up. Opening the answer was simply what started it.

The measurement is now compared before it is submitted rather than after, so an
unchanged value is not submitted at all.

Installing an update no longer blames unrelated programs

An upgrade could refuse to proceed, reporting that processes were "still running
from the installation folder" and naming programs that had nothing to do with
Orgtree — the Windows Command Palette, Copilot, browser components. Retrying
usually worked, which made it look like a glitch.

Windows keeps a record of each process's parent even after that parent has
exited, and the parent's id is then free to be reused by something unrelated.
The installer followed those records to decide what belonged to Orgtree, and so
adopted whole unrelated families of processes. It now checks that a claimed
parent actually started before its child, which a reused id cannot fake.

Agents whose conversation file moved can be woken again

A Codex agent whose stored conversation path no longer matched where its file
actually lived could never take another turn: every wake failed immediately.
Worse, the failed lookup also put the agent into a held state, which stopped it
receiving mail as well.

A resume now retries without the stale path when the refusal is about the path,
and a conversation that has moved is located rather than given up on. A resume
that genuinely cannot be resolved now says what it looked for and where, instead
of naming only an identifier.

Streamed output no longer buries the renderer

Every token an agent streamed went to the interface as its own update, and each
one cost far more than the token itself — the transcript re-measured and
re-rendered, and the draft's text was re-parsed as Markdown from scratch each
time. On a busy organization the interface allocated tens of megabytes per
second to display a few kilobytes of output, and fell further behind the longer
it ran.

Live text now reaches the screen once per frame instead of once per token.
Measured on the same workload: 332 MB down to 33 MB for 960 tokens, and the
desk's lag behind the agent it is showing went from a median of 20.2 seconds
to 24 milliseconds
. Streaming still looks live — it is the same text at the
same speed, drawn once per frame rather than once per token.

An honest limit: this removes a real and measured cost, but whether it is
enough on its own to stop a renderer being killed outright under heavy load is
not established. Most of that process's memory sits outside the part this
change affects.

A window that dies now comes back

If the interface process fails, Orgtree reloads the window instead of telling
you to restart the whole application — the engine and your agents were never
affected, and now neither is your place in the interface. Repeated failures
fall back to the old dialog rather than looping, and that dialog now carries the
reason it failed.

Failures are also recorded. Previously a renderer that was killed left no crash
dump, no system event and no log line of any kind, which made this class of
problem nearly impossible to investigate. Orgtree now writes the reason and exit
code to its own log, and crash dumps are collected locally only — nothing is
uploaded, and there is a tray entry to reach a dump deliberately if you want to
send one.

Restart no longer leaves a wall of raw text

A turn interrupted by a restart was replayed t...

Read more

Orgtree 2.1.5

Choose a tag to compare

@Maurdekye Maurdekye released this 15 Sep 19:15

Orgtree 2.1.5

This release makes self-updating trustworthy, adds staffing straight from the
docket, and corrects what the interface claims about accounts and plans.

Upgrading an existing installation

If you are running 2.1.4, the tray's Update now will find this release and
install it.

Self-updating

  • An update waits until the installer is actually observed running before
    Orgtree exits. A process id coming back is no longer treated as proof, so an
    installer that is declined at the permission prompt, or that dies immediately,
    no longer leaves the application shut down having installed nothing.
  • When an update cannot be handed off, Orgtree says so from a process that is
    still alive to say it. It records the outcome, relaunches, and the relaunched
    instance shows the failure, naming the reason and where the log is. An update
    that was prepared and then failed can be recovered by hand, and ordinary
    update checks resume afterwards instead of stopping.
  • Orgtree is relaunched exactly once after an update. The installer and the
    restart helper settle who performs the launch with a single claim that cannot
    be created twice, and every update carries its own identity, so a reused
    process id can never block a later update.
  • The restart helper waits on a real process handle taken from a host that
    machine policy cannot switch off, and it takes that handle before it promises
    Setup it will wait. If it cannot, Setup keeps the launch itself rather than
    handing it to something that is not there.
  • The post-upgrade relaunch uses the GUI Python host Orgtree already ships
    instead of PowerShell, so no console window appears.
  • Silent all-users updates request elevation before the installer's preflight,
    and the installer reports the elevated child's own result rather than merely
    that it started — an update that was declined or that failed is no longer
    recorded as a success.
  • Closing a console window no longer kills Orgtree cold. Console-close,
    interrupt and break signals shut the application down in order, and closing
    the originating console, the parent shell or the engine cannot cancel an
    update that has already been accepted.
  • Update progress is written to durable phase markers, so an update that ends
    badly can be diagnosed afterwards instead of leaving only silence.
  • The Windows installer writes its own log from its first line onward —
    including the command line it received and whether it had administrator
    rights — and declares its log variables before the code that assigns them, so
    a failure before any page is shown still leaves a complete record. The Finish
    page has a working launch control again.
  • Prereleases now sit on a release line the updater can leave. A beta
    installation receives later betas and the stable release; a stable
    installation ignores prereleases entirely instead of being offered a candidate
    as soon as one is published.

Staffing from the docket

  • A team docket is available behind the agent context menu, and staffing an item
    is recorded as its own readable docket update.
  • Staff… creates the seat and assigns the work in one action, with the same
    progress preservation as an ordinary staffing, and its submenus dismiss in the
    window the right-click came from.
  • The menu asks in one order: model, then effort, then account. Each effort
    row carries the accounts that can run that tier beneath it, and choosing one
    sends the tier, the effort and the account together. An effort taken without
    opening the account list means the account a plain hire would pick. The
    account layer appears only where there is a real choice — a single eligible
    account the tier would take anyway is not one.
  • The menu offers only what can actually be staffed. Availability is judged per
    account rather than against one account only, so a single exhausted Claude
    account no longer greys out every Claude tier while a second account still has
    room; tiers and accounts that cannot be staffed are left out rather than shown
    greyed, because a greyed row is still an offer.
  • The menu is ready before it opens. Provider discovery and its network call
    happen at startup and are shared, a docket row prepares its options when it is
    drawn, and building the trial organization no longer copies chat history, mail
    and event logs that a hire never reads — on a large organization that alone
    was about a second per tier.
  • Models are listed in the same order as the model-switch dropdown: grouped by
    provider, ordered by tier. A tier the provider document does not list keeps
    your organization's own order and goes last.
  • Quick Hire on a backlogged ticket no longer leaves the ticket moved, the
    request posted, and no agent hired. The wake reason is checked when the
    request is sent rather than minutes later on the recipient's turn, and a
    refused kickoff undoes the whole request — the ticket's prior status, its
    progress lists, the manual flag and the receipt. The same class of failure is
    closed for the unstick path.
  • Request staffing runs its discovery outside the document lock, and staffing
    offers are separated from direct-hire eligibility.

Accounts, plans and usage

  • Google AI accounts are labelled with the official paid tier names, resolved
    without the old authentication-method fallback. Gemini and Antigravity
    accounts report the authoritative tier, resolved from probe logs as well as
    structured status, with the capability cache keyed by CLI version so an
    upgrade invalidates a stale reading. A plan row without authoritative metadata
    is omitted from the usage board rather than shown with a guessed tier.
  • A pinned desk shows its account ID once, in its token list, and Codex cards
    keep their serving account across the turn.
  • A frozen agent can be continued on another account from its menu.

Mail and file delivery

  • Direct file delivery no longer refuses an authenticated agent whose
    conversation has resumed. A live seat could be rejected with "caller has no
    durable seat identity" after resumption even while every other operation
    recognised the same agent; the authenticated actor-to-seat handoff now
    preserves an established seat, and a delivery that fails for a transient
    reason can be retried rather than being final.
  • Delivered files are hashed on Python 3.10 as well as newer interpreters, and a
    corrupted delivery receipt is refused with an error that says what is wrong.
  • A retired import binding can no longer silence a mailbox, long managed tool
    calls yield at safe delivery boundaries, and unpublishable tool results are
    retired without consuming active capacity.

Interface

  • The backend restart notice names the installed version above the commit.
    Running from a source checkout says so plainly instead of quoting a release
    nobody installed, and unreadable build metadata says it is unavailable rather
    than guessing.
  • Agent names appear on far-zoom hover, counter-scaled so they stay readable at
    any zoom level, and a zoom-in cursor marks zoomable cards.
  • Context menus open in the window the right-click came from, and presenting a
    document focuses the popped-out window that is already open instead of opening
    another.
  • Questions with no options are presented as free response, bulk subordinate
    retirement is available as a context action, and the canvas halt outline is
    limited to the organization killswitch.

Testing

Tests that disturb the desktop — ones that open consoles, show dialogs, or run
the real installer toolchain — sit behind two barriers. An ordinary npm test
cannot reach them, and each refuses to run without an explicit opt-in, so
running the suite can no longer take over the machine.

Orgtree 2.1.4

Choose a tag to compare

@Maurdekye Maurdekye released this 14 Sep 12:54

Orgtree 2.1.4

This release finishes interactive upgrades without any clicks after approval,
brings account cards to every provider with multiple accounts, and improves
mail and messaging behavior.

Upgrading an existing installation

A successful interactive upgrade now completes on its own: Setup closes
automatically when it finishes, and Orgtree starts exactly once after Setup
exits. Fresh installs, failed or cancelled upgrades, and silent automatic
background updates behave as before.

Account cards

  • Account cards appear for every provider with multiple registered accounts —
    Claude and Codex alike — on agent nodes, desk headers, and pinned desk title
    bars, using compact card typography.
  • The visible account token is default for the provider's default
    subscription account, the immutable secondary account ID for a secondary
    subscription account, or the first 8 characters of the key for API-key
    authentication.

Mail and messaging

  • Reply navigation uses a compact jump link, and expanded messages remain open
    after sending.
  • Message delivery at turn boundaries is durable across restarts and queued
    work.
  • Mail addressed to the user supports attachments without an artificial size
    cap.
  • Mailhub joining uses address-only configuration for simpler, predictable
    connections.
  • External inbox access is limited to one holder, and revealed retired agents
    can be dismissed directly.

Interface

  • Far-zoom views keep model-token information visible, and Codex cards show
    serving-account details accurately.
  • The Antigravity secondary-account modal links to
    google-antigravity/antigravity-cli issue #381 when managed or imported
    account sections are unavailable.

Everything else

Fresh installs, uninstalls, the advanced setup path, install location and
scope selection, and automatic background updates are otherwise unchanged.

Orgtree 2.1.3

Choose a tag to compare

@Maurdekye Maurdekye released this 13 Sep 21:38

Orgtree 2.1.3

Most of this release is about one thing: making Upgrade work when you run
Setup over an installation you already have. The installer is unsigned, as
earlier Orgtree releases have been.

Upgrading an existing installation

Running Setup over an existing Orgtree installation offers to Upgrade it.
Upgrade reuses the install location and the scope already recorded for that
installation, so there is nothing to re-choose and no risk of a second copy
landing somewhere else. Advanced setup is still there if you want the full
wizard.

Administrator approval is asked for once, up front. An all-users upgrade has
to replace files in C:\Program Files, which requires it. Setup asks when the
install mode is settled, before anything is touched. If approval is declined or
fails, Setup says so and stops: it never continues without the rights it needs,
and it never leaves the existing installation half-replaced.

The upgrade stays on screen after you approve. Approving the prompt hands
the work to a second copy of Setup running with administrator rights, and that
copy shows its own Installing page and then its final page. The first copy
hides itself so you are never looking at two Setup windows or at one that
appears frozen.

The final page offers to start Orgtree, as usual. Leaving Run Orgtree
ticked starts the application when you close Setup, and it starts without
administrator rights even though the upgrade needed them.

Automatic background updates are unaffected. When Orgtree updates itself
rather than being upgraded by hand, it installs silently and restarts on its
own, with no window and nothing to click.

Orgtree is closed gracefully, and never force-killed. Setup asks Orgtree to
shut down and then waits for it. If something is still running, or cannot be
verified as closed, Setup names what is holding it and offers Retry or Cancel —
it does not kill anything, and the installed application and your data are left
untouched.

"Closed" means the whole installation, not just the visible window.
Orgtree's engine runs from a separate program inside the installation folder and
starts subprocesses of its own, none of which is called Orgtree.exe. Windows
will not let an installer replace a program that is still running, so all of
them have to be accounted for. Three details make that a real check rather than
an optimistic one.

  • It refuses when it cannot see. The list of running programs is read two
    independent ways, and if neither can be read the upgrade stops and says so,
    instead of treating "nothing found" as "nothing running".
  • It looks before it asks. Everything running from the installation is
    written down before Orgtree is asked to close, and each one has to be seen to
    exit — not merely to be missing from a later look.
  • It does not lose track of children. If a program inside the installation
    starts a helper and then exits, that helper is still recognised as part of the
    installation and still has to finish, whether it appeared before or after that
    first look.

Lifecycle logging

If an upgrade ever does misbehave, it leaves a record. The installer writes each
step and its outcome to %TEMP%\orgtree-installer-upgrade.log, and Orgtree
itself records the shutdown request arriving, the shutdown beginning, its engine
stopping, and whether it completed or was refused. A log that cannot be written
is never itself a reason for an upgrade to fail.

Between them, these two records are usually enough to explain a failed or
surprising upgrade without needing to reproduce it.

Interface changes

  • The account serving an agent's running inference is shown on its card.
  • A divider marks where queued chat messages begin.
  • Far-zoom agent nodes render a single enlarged state icon.
  • Pop-out modal minimum sizes match their pinned forms, and the Agents list
    width is reconciled.
  • The Docket badge counts actionable owned work correctly.
  • orgtree_staff transcript entries carry docket links.

Everything else

Fresh installs, uninstalls, the advanced setup path, install location and scope
selection, and automatic background updates are otherwise unchanged.

Orgtree 2.1.2

Choose a tag to compare

@Maurdekye Maurdekye released this 13 Sep 07:07

Orgtree 2.1.2

One fix since 2.1.1. The installer is unsigned, as every Orgtree release before it
has been.

Start Menu

  • Upgrading no longer leaves the old "Orgtree v2" Start Menu entry sitting beside
    the current one. 2.1.1 already tried to remove it, but an all-users install only
    cleaned the all-users Start Menu, and on most machines that entry is in the
    installing user's own Start Menu instead, so it survived. The cleanup now names
    each Start Menu scope explicitly and removes the old entry from both, whether
    the installation is for all users or for one.
  • Only that one legacy name is removed. Your current Orgtree shortcut is left
    alone, no other shortcut is touched, no Start Menu folder is scanned, and
    side-by-side development builds are unaffected.

Orgtree 2.1.1

Choose a tag to compare

@Maurdekye Maurdekye released this 13 Sep 02:16

Orgtree 2.1.1

Changes since 2.1.0, which is published on GitHub as the previous release. The
installer is unsigned, as every Orgtree release before it has been.

API keys become ordinary accounts

The old path treated an API key as something one organization owned, set in that
organization's Autonomy tab, with a red border on the office and the agent card
whenever a turn spent it. That whole path is gone, replaced by accounts.

  • An API key is now registered the same way any other account is: "Use an API
    key" in the add-account dialog, for Claude and for Codex, whether or not that
    provider's subscription is signed in. Google is not offered, because
    Antigravity has no API-key login.
  • Key material is kept in the machine token store for both providers. The
    account row holds only a reference to it, never the key itself. Removing the
    account disposes of the secret; subscription logins cannot be reached through
    that door.
  • The Usage panel answers a key account with what it has actually cost in USD,
    plus its turn count, instead of limit bars that could only ever read 0%. An
    account that has never run reads as "never used" rather than as $0.00 spent.
  • Two machine-wide switches sit under each provider's account list, because they
    are statements about those accounts: whether signed-in subscriptions may serve
    turns at all, and whether a turn may reach an API-key account once every
    applicable subscription limit is exhausted. Both now act for the provider they
    name — previously they were wired to Claude only while the interface offered
    them for Codex and Antigravity as well. The fallback switch stays hidden until
    an enabled key account exists for that provider.
  • API-key fallback is off by default and fires late: a turn reaches a key
    account only once no subscription can serve it. Turning subscription inference
    off for a provider routes that provider's unbound turns to its first enabled
    key account immediately.
  • An agent bound to a specific account is never silently rerouted. If its
    account cannot serve, the agent is parked and says so, because moving a turn
    off an explicit binding is exactly what the account rules forbid.
  • Codex can now start on a key alone. It previously refused before it had worked
    out which account would pay, so key-only operation was unreachable on that
    provider.
  • A key whose credential has been judged unauthenticated is skipped instead of
    holding the lane, so a revoked or mistyped key no longer absorbs every metered
    turn while a healthy key waits behind it.
  • A Codex rate limit is now recorded against the key that actually hit it, so
    multi-key rotation moves on to the next key rather than retrying the walled
    one. Subscription rate-limit handling is unchanged.
  • Existing organization API keys are migrated into the account registry at
    startup. Bindings survive, the machine fallback switch stays off, and a
    partial migration finishes on the next start rather than blocking it.
  • Account selection surfaces name the host login explicitly, and capability
    conclusions are dated so a stale reading is visible as stale.

Mail hub hosting moves to App Settings

One installation hosts at most one mail hub, but everything about that hub —
whether it listens, where, with which certificate, and which organizations it
admits — was rendered inside a single organization's Connections tab.

  • Hosting and grant administration are now in App settings, under a new Mail hub
    tab. An organization's Connections tab keeps only that organization's own side:
    its address, with a copy action, and the hubs it connects out to.
  • The grant list is new. The hub always knew which grants it had issued and could
    revoke one, but there was no way to read them. App settings now lists each
    allowed organization with its state, revokes a grant, and replaces a credential
    by rebinding a new secret to the same identifier and organization.
  • Authentication is untouched: same token format, same fingerprint admission,
    same exact-organization binding, same TLS verification, same manual exposure.
    Existing hosting configuration, credentials and connections survive the upgrade
    with nothing to re-enter.

Notifications and attention

  • While any attached question, attention ticket or urgent mail is still waiting,
    the Windows taskbar button uses the platform's own attention behaviour and the
    matching toolbar icon carries a small bright dot. Both read one
    cross-organization total, so they cannot disagree; they clear together when
    nothing is left waiting.
  • A question card no longer suppresses its own alert merely by being on screen. A
    window on a second monitor, or behind whatever the user is actually working in,
    has shown them nothing, so suppression now requires the card to be in the
    Orgtree window they are in. A deferred alert arrives on the first poll after
    they leave Orgtree; one they genuinely saw stays consumed.
  • A busy organization can no longer starve notification delivery. Continuous
    saving used to dirty every dispatch pass before it finished, so nothing reached
    the operating system at all.
  • A master notifications switch with safe defaults, plus per-category native
    notification settings.

Tickets and the Docket

  • Docket next actions and handoff requests are routed to the agent that holds the
    next action.
  • Ticket descriptions keep a history of scope changes, so a later reader can see
    how the stated scope moved.
  • A refused docket write leaves the item byte-identical. A refused reopen, and
    any refused update, no longer leaves a partial change behind, and a docket
    write is never silently truncated.
  • Docket categories can be collapsed.
  • Ticket evidence is classified by how it was obtained, and an acceptance
    condition can require an executed known-negative control rather than an
    unfalsifiable claim.
  • A rename records that a rename happened instead of rewriting the earlier record
    as though the new name had always been there.

Transcripts and history

  • Reading back through a desk's history keeps the reader's place, anchors on
    their own row, and makes a failed page load retryable instead of silently
    stopping.
  • Every page request now settles with an outcome, including a failed automatic
    load of an older page, and the viewport keeps its floor through a failure.
  • Transcript paging state is released when the renderer resets, and a stale page
    cleanup can no longer discard a newer one.
  • Sending from a history view does what the user chose, pinned by a regression.

Windows, popouts and appearance

  • A popped-out modal is a window, so it has a title bar; and a dialog inside a
    window is no longer treated as that window itself.
  • Claude agent rows use the shared provider theme.
  • Windows development builds carry the branded taskbar metadata.
  • The legacy generic-icon Start menu shortcut is removed, so an upgrade no longer
    leaves a second unbranded entry behind.
  • A mail fold is measured when its body changes rather than on every render.
  • Halt sits beside the other top agent lifecycle actions.
  • App Settings charter text, provider actions and section headers are tidied.

Reliability and diagnostics

  • Restart notices report the packaged build identity, so an operator can see
    which commit and version the running installation came from.
  • A read-only installed-runtime verifier reports runtime identity and discovery
    without provisioning, starting, stopping or deploying anything.
  • Scoped runtime and effective-scope diagnostics, scoped state inspection with
    transition previews, and a redacted view of an agent's account binding.
  • Worktree operations are safe and visible, and the ticket sweep names what it
    owns instead of quietly excluding it.
  • A turn record distinguishes the send from the acknowledgement, so a refused
    turn no longer reads as "sent and never answered".
  • A watchdog can report that it does not know whether a process is alive. A
    permission error no longer announces a death, and an uncertain observation
    leaves the last known state standing rather than accumulating into a confident
    verdict.
  • Compaction handoffs preserve the facts a successor needs, and breadcrumb
    encoding survives the round trip.
  • Reports are submitted with an explicit audience check.

Verification and development

  • A verification receipt records the candidate commit, a fingerprint of the tree
    the check ran in, the command line, and which of five outcomes came back, so a
    passing log from before an edit cannot read as evidence for after it. A
    supplied base is resolved and proved to be an ancestor rather than taken on
    trust.
  • Stored artifacts are addressed by content hash, names are never reused, and a
    failed record no longer leaves unnamed bytes behind.
  • Shared verification fixtures and replay recipes, scoped resource reservations,
    integration receipts, and recorded review verdicts for a candidate.
  • An isolated Python verification runner gives each test module its own
    interpreter and data root, and renderer and root test runs no longer interfere
    with each other.

Orgtree 2.1.0

Choose a tag to compare

@Maurdekye Maurdekye released this 12 Sep 17:32

Orgtree 2.1.0

Changes since 2.0.9. These notes describe the release candidate; publication is pending.

Accounts and provider usage

  • Choose an account when hiring, rehiring, or retooling an agent, including returning an agent from a managed account to the default sign-in. Account defaults also preserve an explicit choice of the primary account.
  • Account choices consistently show the account ID and email. The primary sign-in appears as default; managed accounts use their immutable IDs. A provider with one available account keeps its choice visible and disables the dropdown.
  • The Usage panel shows account IDs and emails for providers with multiple accounts, and the email alone when there is only one. Legacy custom labels no longer replace account IDs.
  • Agents receive usage, reset times, freshness, and availability for all registered accounts, with updated guidance for choosing accounts and interpreting provider-specific limits.
  • Antigravity usage now comes from its CLI, with account-specific caching and authentication status handling.
  • Frozen agents retain the wake time selected from their rate-limit response, including an inferred-time label when appropriate. The displayed estimate and automatic resume use the same stored decision; a stale account roster cannot erase it. The rate-limit-specific retry is consumed only when an attempt is actually sent.

Agent control and reliability

  • Halt and Unhalt provide a durable way to stop an agent. Halt prevents new turns and preserves pending work across restarts and lifecycle changes until the agent is explicitly unhalted. Interrupt remains available for stopping the current turn.
  • Recovery handles queued model switches, missing accounts, failed remote drivers, and invalid state transitions more reliably, while respecting a durable halt.
  • Lifecycle operations read bounded log data and lighter archive summaries. Large organizations spend less time loading detail that the current view does not need.
  • An Antigravity turn that finishes successfully is no longer reported as failed solely because the CLI omitted its final summary.

Tickets and conversations

  • Ticket descriptions support full Markdown without the former 2,000-character product limit. Long descriptions initially show ten rendered lines and can be expanded. Agent guidance now requires descriptions to contain the complete scope of the work.
  • Ticket references update when the available ticket names change, while unchanged references keep their existing elements in place.
  • Ticket ownership and review assignments follow the same agent through generation changes. Historical authorship stays intact.
  • Assigning a backlogged ticket opens it automatically.
  • Assistant messages reconcile by identity across streaming events and saved transcripts, reducing duplicate or missing text during refresh and recovery.
  • Inline replies show rich previews from the exact replied-to content and retain the shared object context menus.
  • Expanded transcript messages stay expanded while new events arrive. Large history views release their expanded window when the reader leaves history, and active searches can still retrieve the full record.

Desktop and workspace

  • The ordinary Agents window stays inside the available canvas height. Long lists scroll internally; pinned and popped-out windows retain their existing sizing behavior.
  • Agents List rows expose the same context menu as agent cards, including Pop out. Shared menus also provide copy-name and ticket-title actions, and a ticket menu can open immediately after its slug is copied.
  • Close actions now close their corresponding panels and documents consistently.
  • Home and each organization retain separate Usage panel state. Organization Settings also keeps its open state per organization.
  • Popouts open near the surface they came from and preserve its shape. Canvas controls can be anchored to the space left around pinned windows.
  • Choose agent colors by provider or organization, use independent contrast presets, and configure native notification categories and focus behavior.
  • Urgent mail, questions, and ticket attention route to the corresponding request. The Docket button is more prominent when attention is needed.
  • Toolbar menus, Usage spacing, capitalization, and zoomed-out card badges receive smaller usability improvements.

Performance and development

  • Unchanged organization trees can reuse conditional responses instead of rebuilding and transferring the full view. Invalidation prevents stale results from replacing newer state.
  • Background work shares snapshots and scopes process-warming checks to the organizations that changed. Stream identity, closed tickets, and settled logs avoid repeated full-document reads.
  • Event, inbox, and history endpoints use bounded reads, reducing work on large records while preserving access to older content when requested.
  • npm run package:dev creates a local development installer with a distinct application identity, data directory, and commit-stamped version. Development builds keep updates disabled and cannot replace the published installation. See local development builds.