A false-positive patch. Every entry started with the user looking at a screen and saying "that is wrong", and in each case the system was healthy while the tool reporting on it was not: a teardown guard hard-blocking work it was structurally incapable of losing, a roster painting finished members as failures, an observability page presenting a static lower bound as a target that had been overshot. The one genuine defect was found while chasing the others. Surfaces stay put: MCP tools 113, REST endpoints 208, machine checks I1-I14. Tests 2,493 -> 2,556.
Fixed
- Worktree teardown guard blocked on a criterion that cannot lose work (
fde92f7,0568db3) - removing a worktree in a repository whose development happens on a long-lived feature branch was hard-blocked with "810 commits not patch-equivalent". Two defects, both settled by experiment before any code changed. Wrong target:git worktree removedoes not delete the branch, so committed work on an attached branch keeps a ref and cannot be lost (measured: zero orphans after removal); only a detached HEAD orphans anything (measured: the commit vanishes from--all). The guard was hard-blocking precisely the safe case. Wrong baseline: the "main branch" resolved tomaster, while that repository's work sits on a feature branch 1,090 commits ahead of it, so one branch-local commit was reported as 810 units of risk. The criterion is now git reachability - after this command, can any other ref still reach these commits - computed by excluding, ref by ref, everything the command itself would delete (viarev-list --stdin, since that repository carries 210 refs). The four patch-id helpers behind the old proxy were deleted rather than kept, so the old axis has no way back. Fail-closed is unchanged and now covered by tests: a probe that cannot answer blocks. A three-lens adversarial review (false-allow hunting, test-quality audit, engineering integrity) produced 16 findings, all fixed, including one regression against the previous version: the new advisory told the user to delete the branch separately, while branch deletion was only guarded forworktree-prefixed names. Deletion now covers every ref, and the advisory computes reachability on the spot and says outright when a branch is the only thing holding those commits. Also fixed: flag spellings that skipped the guard entirely (-ff,-f --), two same-tip branches alibiing each other within one command, refname case/Unicode folding that failed to exclude the target itself, a fail-open probe on the branch path,rm -rfshapes outside the managed directory, ignored-but-unrecoverable files counting as clean, and only the first operand being assessed. Verified read-only against the reporting user's actual repository: the verdict flips from block to allow, working tree untouched. Out of scope by explicit declaration:git push origin --deleteand batchupdate-ref --stdin. - Late-binding race dropped hook observations (
cbe7735) -_resolve_agent's name-based late binding writescc_tool_use_idonto the row it picks; when a concurrent request had already bound that id to another row, the UPDATE hit the UNIQUE constraint and raised through as an ASGI 500, losing that observation (twice in the production stderr log). The constraint is doing its job - it is what stops two dispatches from sharing one ledger - so the loser now re-reads and adopts the winning row instead of dying, matchingget_or_create_team's existing convention. Unresolvable cases still stay unresolved: losing one observation beats writing to the wrong row. - Workflow plan count read as a miscount (
7c1e3fe) -agent_countroutinely exceededplanned_agent_count(8 against 2 on one run) and the UI rendered it as a bare fraction, so a correct number looked like a broken one. The plan count is a static lower bound: it counts literalagent()calls across every phase, butpipeline(items, ...)writes one call that fans out tolen(items)at runtime, and that width is unknowable before the run. Deliberately not ratcheted up to match reality afterwards - a plan that always equals the actual is not a comparison. The presentation became honest instead: runs with dynamic nodes show>= Nwith the fan-out count in a tooltip, runs whose plan was never parsed (7 file-reconciled historical runs, previously rendered as "75/0") show "plan unknown", the actual takes the headline once a run is terminal, anddynamic_nodesreaches the MCP projections. The static count also stopped countingagent(occurrences inside comments and prompt text - measured across 178 real workflow scripts, 18.5% were inflated that way. New runs only; history is not rewritten. - Finished team members rendered as failures (
6fd72ae) - a long-lived session's container team listed all 44 members flat withofflinein a reddestructivebadge, reading as "40 members never exited" when every one of them had finished normally. Agent rows are deliberately never deleted (audit trail, and the token ledger lives on them), so the folding belongs in the view: active members stay expanded, finished ones collapse into a single "past members N" row that expands on click, andofflinein a member context now reads "finished" in a neutral badge. The globalofflinestring is untouched, because on a Leader row it means the session ended.
Changed
- PyPI distribution line deprecated and yanked (
41292fd) - the wheel had sat at 1.3.4 since April while the repository moved to 1.11.x, with no deprecation marker on the page:pip install ai-team-oshanded newcomers a four-month-old build that ships withoutplugin/and the config resources, whose post-install step never worked and structurally cannot (PEP 517 wheel installs execute no code). All 10 releases are now yanked with a reason pointing at the plugin and source paths, 20 of 20 files confirmed. Measured before deciding: 46 non-mirror downloads in 30 days and 0 in the last 7, against 577 unique clones of the GitHub repository in 14 days - the pip channel was not carrying distribution. Both READMEs corrected: the roadmap claimed the line was frozen at 1.2.0 when it had in fact shipped through 1.3.4.