QA re-verification run: confirm the fixes for the #656 findings (post-fix pass for Opus) #697
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Cordy/Cairn#697
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This is the post-fix companion to the #656 QA pass. The findings (#657–#695) are being fixed in batches; each batch that ships gets a section below with the deployed version and per-issue verification steps. Do not start until Nikola points you here — batches are still landing and each section names the version it needs.
Protocol (same as #656 unless stated)
files.c0rdyceps.ch(enc/Keycloak) andfiles-bao.c0rdyceps.ch(OpenBao/local). Sign-ins as in #656: nikola-test via Chrome on both hosts, sharer1 in-app on files-bao only._qa/folders. Screenshots as filename references. One comment per finding here (PASS/FAIL + evidence); do NOT open new issues for regressions of these fixes — a FAIL comment referencing the original issue number is enough. Genuinely new findings unrelated to a fix still get their own issue on the v0.7 milestone.Batch 1 — sharing correctness, v0.6.248 (#680 #676 #677 #678 #682 #679)
_qafile → type into "Search people and groups" → press Enter. Expect: NO public link created (GET /api/v1/sharesunchanged), no Public chip. Enter with a picked candidate should act as Add. Creating a link still works via the Create link button.#loc:nikola-test:/…. (a) Open it in a fresh tab as nikola-test: folder loads, or file opens parent + details pane. (b) Paste it into an ALREADY-OPEN tab: same result via hashchange, no reload needed. (c) As sharer1 (files-bao, for something shared to them) the link should land in their/shared/nikola-test/…view — note: deep paths inside a shared folder resolve to the shared root's basename only, by design. (d) An old bare-path link still works for the owner._qafolder on the ENCRYPTED instance (files), open it signed-out, drop a file. Expect: upload succeeds (was: silent 500). The written file belongs to the link creator.(further batches will be appended as they ship)
Batch 2 — admin and departed-owner correctness, v0.6.249 (#686 #687 #688 #689 #690-partial #658 #657)
All on files-bao unless noted; needs at least v0.6.249 on the footer.
sharer2(or any departed name from the Departed tab) — expect it NOT offered as a recipient anymore (live accounts still are); (b) Administration → Users & access → Accounts → Directory accounts — the departed account carries a "Departed — the directory no longer resolves this account" chip and offers NO Make-admin action. Live accounts unchanged.qa656(holds the_qa/dropview grant) — Used by now reads "1 share" (plus any other bits), not "Not used". A group with no grants still reads Not used./home/sharer2/README.mdlink flagged "Frozen — owner departed" with no Copy button. Revoke works for links you don't own (admin revoke) — please only exercise it on_qalinks.Batch 3 — legal holds, v0.6.250 (#685 #683)
Needs at least v0.6.250. Use files-bao
_qa/for the live tests; the two bogus holds live on files._qafile, then Retention & holds → Retention → "What applies to a path" → resolve that exact path, its PARENT folder, and a path INSIDE a held folder. Expect each answer to include a bordered "Legal hold:<path>— placed by … · date · reason" line. A path with no hold shows none./Fall 1(or any nonexistent path) — expect a 400-style inline error "no such path … check the namespace (/home//… or /spaces//…)" and NO new hold in the list. A real storage path still gets a hold (201, appears in the list).hold-liftevent carries the reason (check Audit log → the event's note, or the raw JSONL if the viewer doesn't render notes — the field isnote).Batch 4a — protocol honesty, v0.6.251 (#665 #670 #671 #672)
Needs at least v0.6.251.
_qaoffice file in Collabora, save, Back. Expect: server log shows NO "versions: mint failed … Invalid signature", details pane → Versions lists at least one previous version with Restore/Download, andGET /api/v1/versionsis non-empty for the file. Note: versions only exist for edits made AFTER this deploy — the old silent failures are unrecoverable.PROPFIND /dav/home/_qa/ Depth:1— the collection's own response either carries a realgetlastmodifiedor omits the property entirely; no "Mon, 01 Jan 0001" anywhere in the multistatus.qa-sheet.xlsx— the pane hero renders the first page via the converter on BOTH hosts;GET /api/v1/preview/formatsnow includes xlsx, xls, ods, csv. A csv preview is worth one spot check.(#659 plaintext sizes and #664 preserved Modified are deliberately NOT in this batch — they ship next as batch 4b.)
Batch 4b — logical size and content mtime, v0.6.252 (#659 #664)
Needs at least v0.6.252. Important scoping: only files written AFTER this deploy carry the new record — pre-existing files keep showing backend (ciphertext) values until their next write. Test with fresh
_qauploads.getcontentlength== GET/HEAD length,/api/v1/filessize matches. Repeat one file on files-bao._qa/sub/. Expect Modified unchanged through both (UI + PROPFINDgetlastmodified). A CONTENT edit (Collabora save) still updates Modified..cairn-meta.json(no.cairn-versions/.cairn-meta.json/...writes on tag/favourite/upload churn).Batch 5a — navigation and views, v0.6.253 (#668 #667 #666 #669 #684)
Needs at least v0.6.253. Either host unless noted.
#view/<name>. Reload on each: you land back on that view. Paste#view/sharesinto a running tab (change the hash of an open tab): the view switches without reload. Personal and Spaces still use#/path.#/favoritesor#/home/gone-folderand reload. Expect: a toast "That location doesn't exist (anymore) — back to Personal.", landing in Personal, NO leftover rows from the previous folder and no raw "Load failed: not found…" line.#admin/peering/global(reload lands on the tab). Toggling the switch off/on should 503/un-503 the send APIs as before — verify state restores after your test.#loc:internal links and#admin/...routes still work (same router touched).Batch 5b — activity feed, v0.6.254 (#673)
Needs at least v0.6.254. Only events from AFTER this deploy exist — the old feed was never written.
_qafile (any method: button, drop, or a large file via resumable upload) → details pane → Activity shows an "upload" event with your name..cairn-internal churn (tags/favourites writes) creates NO events for the manifest, and events never appear for another user's actions you can't see.Batch 6 — picker polish and one empty state, v0.6.255 (#660 #661 #662 #663)
PR #704, merge
e6b12ca3, live on both dogfoods.#660 — duplicate empty state. The redundant
say(t("emptyFolder"))status-bar line was removed from the listing renderer; an empty folder now shows only the single in-panel empty state. Verify: open an empty folder — no second "This folder is empty" in the status area.#661 — picker button gives no disabled feedback. Added
.pickfoot button:disabled { opacity: .5; cursor: not-allowed; }. Verify: open Move/Copy, select a destination where the action is not allowed (e.g. the source folder itself) — the primary visibly dims.#662 — picker breadcrumb shows the storage segment.
pickRootOfnow returns/homefor paths under it, andpickRootLabelmaps both/and/hometo the Personal label. Verify: in the picker, navigate into Personal — the breadcrumb root reads "Personal", never "home" or the storage mount name.#663 — folder rows show no child counts. The picker read
it.itemCountwhile/api/v1/filespublishes the count asitems(fillItemCounts, capped at 100). The renderer now readsitemswith anitemCountfallback:Verify: picker folder rows show "N items" (pickCount1/pickCountN, i18n ×4) for folders the API annotates.
Regression pins:
web/test/qa6.test.js(static pins on index.html: single empty state, disabled CSS present, /home root mapping,it.itemsread with fallback, key4 i18n checks).Batch 7a — dark-theme contrast + dialog canon mechanics, v0.6.256 (#691, part of #693)
PR #705, merge
d659e1c6, live on both dogfoods.#691 — dark themes: white on lightened accent, 2.0–2.3:1 (CLOSED). The newer token system already carried a correct per-theme, per-accent-variant
--accent-ondark ink; the old button rules just never read it. Eight sites switch from hardcoded#ffftovar(--accent-on, #fff):button.primary/label.btn.primary,#avatarbtn(+ its dark override nowvar(--accent-on, var(--snow))),.pgn.on,.ksstep.done .kssdot,.ksbtn.primary,.uav.adm,.uabtn.primary. Off-token greys:.rochip→var(--lichen)/var(--slate-700),ul.plainlist .muted/.empty→var(--slate-400), all with fallbacks. Deliberately unchanged: danger buttons keep#fff—--danger(#a8543f) is not lightened in the dark themes, so white passes AA there;.kvbadge.good/.tealstate tints left (deliberate tints per the issue). Verify: Night/Dusk/Ebony/Slate → "Upload file" primary shows dark ink on the light accent (≈8:1+), including with moss/ember/graphite accents.#693 — dialog canon (PARTIAL, issue stays open). Mechanics done:
askConfirm(message, verb)labels the primary with its verb — Delete (file delete ×2), Revoke (share ×2, app password, peer key), Remove (peer), Delete forever (purge) — instead of OK;askNamegainsokand all four callers name Create/Rename;#namedlg-inputgets an accent focus ring; licence dialog puts Close before "Refresh licence" and en spells Licence (keylicense,tabLicense, markup h2). New keys ×4: confirmVerb{Delete,Revoke,Purge,Remove,Create,Rename}. Left open on #693: fact-row rebuilds of#confirmdlg(design work, mockup-first),#pickdlg/#peeraddlg/#peerdetaildlg/#spcdetaildlgstructure, and the legacy dialog trio — confirmed dead:openSettings()has zero callers, so#settingsdlg/#auditdlg/#holdsdlgare unreachable; not removed here because their wiring ($("set-close").onclicketc.) runs at script load and ripping them out is its own change.Regression pins:
web/test/qa7.test.js.Batch 7b — admin shell i18n + style-guide sweeps, v0.6.257 (part of #692, part of #694)
PR #706, merge
9ad07a4c, live on both dogfoods. This was the final batch — see the wrap-up below.#692 — i18n gaps (PARTIAL, issue stays open). Root cause found: the admin sidebar buttons carried (overview) or now carry (
admT_*, injected on the other 15)data-i18n, but 15 of 16 keys were absent from the dictionary, and applyI18n silently skips missing keys — hence the English sidebar. Fixed: all 16 nav keys ship ×4 (product names Cairn Peering / Open Cloud Mesh stay untranslated by design);ADM_TOPICSnow stores key names andadm-title/adm-crumb/adm-descgo throught()with 16 newadmD_*lede keys ×4; sidebar section headers Shared / This instance becomenavGrpShared/navGrpInstance. Transliterations accented: Übersicht, Aperçu, {n} élément(s), Vérifier les mises à jour, Update-Prüfung/für, configurée/è configurato, Géré par le fournisseur d'identité, Récupération, Détention, verschlüsselt (encOffB). Verify: switch to de/fr/it → admin sidebar, page titles and ledes translate; fr Overview reads "Aperçu".Left open on #692: further ASCII-only strings in the dict (other "verschluesselt" carriers exist — the test pins encOffB's own line and notes the residue); the Sharing-policy hint strings (their
sd*keys ARE translated ×4 and mapped atset-f-*— re-verify on v0.6.257 whether the admin pane renders them, the QA run was on .247); fr file-type subtitles are largely a false positive ("PDF document" is ext + fr "document" — byte-identical to en by coincidence; only the word order differs from "document PDF").#694 — roll-up (PARTIAL, issue stays open). Done:
.kvbadgefollows the badge canon (pill 999px, 10.5px, 700, uppercase, letter-spacing); the sidebar storage meter re-renders on language switch (sideQuotaAt = 0; sideQuotaSoon()in the prefs handler). Left open: off-scale rem font sizes, lowercase inline actions, mono OCM buttons, UA-blue release-notes link, off-palette banners, red departed count, native selects, mono/sans swaps, raw gRPC error and bare 404 link pages, UTC labels, Collabora copy, 44px touch targets, singular/plural "legacy servers".Regression pins:
web/test/qa7b.test.js(includes a dynamic pin: every admnavdata-i18nkey must exist in the dictionary — a new topic without translations fails the suite).Wrap-up — all seven batches shipped
Releases in this pass, all live on both dogfoods (files.c0rdyceps.ch and files-bao.c0rdyceps.ch): v0.6.248 → v0.6.257 (ten releases). Fully closed: #657 #658 #659 #660 #661 #662 #663 #664 #665 #666 #667 #668 #669 #670 #671 #672 #673 #676 #677 #678 #679 #680 #682 #683 #684 #685 #686 #687 #688 #689 #691. Partial with tracker open: #690 (structural question pending Nikola — comment on the issue offers the two options), #692, #693, #694. Deferred by prior agreement: #674/#675 (→ #389 phone pass), #681 (mockup-first), #695 (OpenCloud run with Nikola), #654.
@Opus: each batch section above carries per-issue "Verify:" steps. The regression pins live in
web/test/qa1.test.js…qa7b.test.jsand run in CI on every PR.#693 completion — dialog canon, v0.6.258 (CLOSED)
PR #707, merge
29ce3b3e, live on both dogfoods. This finishes what Batch 7a left open.Fact-row destructive confirms. New shared
#dangerdlg(h2 title,.conseqfact rows, Cancel before a named.dangerverb), generalizing spacedeldlg's.crow/.cico/.ctextCSS via shared selectors, plus mono path styling. All eight destructive confirms migrated off the askConfirm prose blob: file delete and bulk delete (title/verb Delete; mono path or bold pluralised count; "Goes to Deleted files…" note), link revoke ×2 (Revoke link; mono path; "The link stops working immediately."), app-password revoke, delete-forever (warn row "This cannot be undone."), peer remove, peer-key revoke.askConfirmkeeps exactly one caller: the trivial peer enable/disable toggle. New keys ×4: dgRevokeLink/dgRevokePw/dgRemovePeer/dgRevokeKey/dgNoteTrash/dgNoteLink/dgNotePurge. Verify: delete a file → titled dialog with trash icon, mono path, restore note, red Delete button; purge from Deleted files → amber warn row + "Delete forever".Structure. peerdetaildlg gains a title (
peerDetailTitle×4); peeraddlg/peerdetaildlg/spcdetaildlg swapactions dlgfootfor canonical.dlgactions.#pickdlgis now a documented exception indocs/design/style-guide.md(composite footer carries the destination readout; New-folder is a tree action).Dead trio removed.
settingsdlg/auditdlg/holdsdlgare no longer dialogs — they are hidden parking-lot<div>s whose children (the set-* fields, audit filter/list, hold form/list) remain exactly where the admin shell adopts them from at open. Removed for good:openSettings(zero callers), the set-close/set-save/set-audit/set-holds/audit-close/holds-close buttons and their boot wiring, and saveSettings' dialog close. Untouched and pinned:ensureSettingsInShell,saveSettings, theadm-save-*buttons. Verify: admin → Basic settings/Audit/Retention→Holds all load and save as before; no console errors at boot; DOM contains no<dialog id="settingsdlg|auditdlg|holdsdlg">.Regression pins:
web/test/qa693.test.js(includes machinery-intact pins); qa7.test.js caller-count pins superseded there.#692 completion — i18n, v0.6.259 (CLOSED)
PR #708, merge
49bf6f85, live on both dogfoods. This finishes what Batch 7b left open.121 transliterated de/fr/it strings repaired. A scanner over every dictionary line flagged ASCII-only values matching per-language transliteration patterns: Schluessel→Schlüssel, cle→clé, identita→identità, fuer→für, deja→déjà and kin, plus missing French (l'/n'/qu'/d') and Italian (un'/l'/dell') apostrophes — clustered in the encryption panel (enc*), licensing (lic*) and the peering lead/confirm strings. The splice was enforced both ways: every flagged string needed a correction, every correction had to be used exactly once. Four scanner rounds were needed — 50 strings had hidden behind em dashes (the original ASCII gate treated "—" as proof of localization; it now strips typographic punctuation first) or behind pattern gaps (identitaet, laeuft, instantane, missing-apostrophe "l " forms).
The scanner is now a permanent CI gate:
web/test/qa692.test.jsre-runs the same scan on every PR, so any future de/fr/it string written without its accents fails the suite with the offending key and text in the assertion message.Settled from the original report:
t(SET_DESC[id])with translatedsd*keys (pinned in the test). Verify: admin → Sharing → Policy in de/fr — the explanations under the labels translate.Verify: switch to de → Licensing shows "Schlüssel installieren", Encryption → Custody shows "Verschlüsselung im Ruhezustand"; fr → "Clé installée.", "N'expire pas"; it → "Home più grande", "Perché ibrido". Grep-level check: the served index.html contains no "Schluessel", no
"Cle", no"Apercu".#694 completion — style-guide roll-up, v0.6.260 (CLOSED)
PR #709, merge
79569c21, live on both dogfoods. This finishes the roll-up.Type scale. All ~100 body-copy
remfont sizes snapped to the px scale (10.5/11/11.8/12/12.5/13/14/15) by a deterministic nearest-value sweep; sizes above 1rem (headings) untouched. Verify: computed font sizes on ledes, kv rows, .sharepath, "Exit to files" land on the scale.Voice & copy. Inline actions are sentence case (Revoke, Remove, Restore, Delete forever ×4 languages). "Last seen" → "Last sign-in", which is what the field holds. The legacy-servers OCM status pluralises via
tn(newocmStatusTrustedV1×4), and every " - " inside the dictionary became " — " (sweep, ~40 strings). Both sweeps are now CI scanners inweb/test/qa694.test.js.Controls & colour. Selects get the canonical border/radius/accent focus ring globally; the release-notes link takes the accent colour instead of UA blue; OCM Check/Allow leave the mono font; the departed-owners tab badge goes muted 11px;
@media (pointer: coarse)grows row actions to 42×44.Times.
fmtTimeRawrenders in the browser's timezone (was unlabeled UTC — a delete at 12:00 local showed 10:00). Verify: Deleted files timestamps match wall-clock (TZ Europe/Zurich).Residue (consciously out, no tracker reopened): kvbadge state-tint drift and Overview-vs-Custody "On" colour (deliberate tints per the issue text); the Deleted-files retention banner (dynamic DOM — needs the v0.7 live pass); raw gRPC text in Transfers (only reproducible with real peer traffic — folds into the #106 A↔B dogfood); bare Go 404 for expired links (server-side, worth its own small issue if it grates); "Signed in now" count semantics (data question); Collabora welcome popup and READ-ONLY SPACE label (Collabora-side); public share page palette (own surface).
With this, all four QA trackers (#691 #692 #693 #694) are closed. Everything from QA run #656 is now either shipped (v0.6.248 → v0.6.260), deferred by explicit agreement (#674/#675 → #389, #681 mockup-first, #695 OpenCloud with Nikola, #654), or awaiting Nikola (#690 — mockup delivered separately).
#690 — opt-in group space (v0.6.261, PR #710)
What changed
/spaces/<group>:scope.Driver.WithGroupExclusion(GroupStore.Has)kills synthesis in both the/spaceslisting and direct path resolution (IdP groups untouched; a store-backed space of the same name still grants)."<group> space"(tracks the group name until hand-edited, resets on close). The interimguNewSpaceNote"for now" hint is gone (markup + key + old qa2 pin).spacestore.Space.Group. Group member add/remove mirrors into it (owner never evicted). Space-creation failure surfaces as a toast (guSpaceFailed), never fails the group create.DELETE /api/v1/admin/groups/{id}?space=delete|keep, 409 naming the space when the fate is missing.Owned by <owner> · group <name> · app-managed(spaceEntry.Group); Groups rows carryspace(appGroupRow.Space).Verify on either dogfood (files.c0rdyceps.ch / files-bao.c0rdyceps.ch, both on v0.6.261)
qa690a, membersharer1, checkbox OFF → create./spacesfor sharer1 must NOT containqa690a; Spaces admin must not list it. (This is the #690 root-cause fix — pre-existing synthesized spaces liketest5also disappear from members'/spacesnow, since synthesis is gone. Their stray backend dirs remain until Nikola's manual cleanup.)qa690b, membersharer1, checkbox ON → Space-name prefillsqa690b space; edit the group name and watch the prefill track until you type in the space field. Create → Spaces admin showsqa690b space · Owned by <you> · group qa690b · Members 1 · app-managed; sharer1 sees/spaces/qa690b spaceread-write.qa690b→ space membership follows (owner never removed).qa690b→ dialog shows the fate radios naming "qa690b space"; pick Keep → space survives, group column empty. Recreate + delete with the default → space lands in Deleted files, name reserved.Tests:
internal/storage/scope/scope_exclude_test.go,internal/spacestore/grouplink_test.go,internal/api/groups_space_test.go,web/test/qa690.test.js; stale interim pin inqa2.test.jsretired. Full suite green on PR #710 CI (1m23s).#681 — federated share from the panel (v0.6.262, PR #712)
Root cause (deep-dive result): the panel's federated Add path from #603 was complete (pick →
POST /api/v1/ocm/shares, allow-list-checked, interop-green), but its ONLY candidate source was the invited-contacts list — a policy-"any" server with zero contacts could never surface a candidate, and typing deliberately resets the pick (the #571 guard)./api/v1/recipientsstaying local-only is by design (user-enumeration guard) and unchanged.What changed (UI only): typing a full
user@serveraddress now offers a direct Federated candidate in the picklist whenserveris on the allow-list with policy "any" (canonical fqdn, case-insensitive host match, deduped against contacts). Picking it enables Add and sends over OCM exactly as before, boundary note included. New pure lift-block helpershareFedDirect+shareFedServersloaded on dialog open. "Invited contacts only" servers keep the contacts-only flow; a non-allow-listed host still offers nothing.Verify on the dogfoods (both on v0.6.262; files → files-bao has policy "any"):
_qa/qa-note.md→ Shares → typesharer1@files-bao.c0rdyceps.chwith real keystrokes → a picklist rowsharer1 files-bao.c0rdyceps.ch · Federatedappears; click it → Add enables and the boundary note shows; Add → "Federated share created."sharer1@not-allowed.example→ no candidate, Add stays disabled (unchanged, intended).sharer1@FILES-BAO.c0rdyceps.CHstill offers the candidate with the canonical fqdn.This unblocks the rest of QA §5 (accept/decline inbound, federated revoke, Shares-view federated rows — untested in the #656 pass).
Tests:
web/test/qa681.test.js(lifted-helper unit pins + wiring pins), full suite green on PR #712 CI (1m21s).#713 — spaces row menu clip (v0.6.263, PR #714)
Found by Nikola during the #690 dogfood-space cleanup. Root cause: the spaces list
.kvboxinheritsoverflow: hidden(rounded-corner clipping), and the row three-dot menu is an absolutely-positioned.pmenuinside.pkebab— so on rows near the table edge the popup clipped instead of overflowing. The Seats tab had the identical bug and already carried the fix; the spaces list now has the same rule (#adm-spaces .kvbox { overflow: visible; }).Verify: Administration → Spaces on either dogfood (v0.6.263) → open the three-dot menu on the LAST row → the menu renders fully past the table's bottom edge. Spot-check Seats row menus still overflow too (regression guard is pinned in
qa713.test.js).#715 — verified IdP attribution, orphan folders surface honestly (v0.6.264, PR #716)
Found by Nikola right after #713:
test5/qa656/Fall *still read "Managed by the identity provider" although Keycloak has no such groups. Root cause:mergeSpaceDirsassumed IdP management for every unclaimed/spacesdirectory — the directory was never consulted.What changed: the inventory now verifies the claim.
GroupsAPI.DirNamesForcollects known directory names plus the live IdP listing; only a successful live listing is authoritative. A dir the directory knows → "Managed by the identity provider". A dir matching nothing →orphan: true, shown as "Folder in storage — no managing group found" (row + details dialog, i18n ×4). No client configured, or listing error → old attribution stands (an IdP outage never mass-flags orphans at a customer).Verify (either dogfood, v0.6.264):
test5,qa656,Fall 1-3,case-folder-1,Test Ümlauf folderinö,cairn-admins*) now read "Folder in storage — no managing group found"; app-owned rows unchanged.*
cairn-adminsonly flips if it isn't a real Keycloak group — if it IS one, it correctly keeps the IdP label.Tests:
internal/api/spaces_orphan_test.go(orphan split, unverified fallback, DirNamesFor authority incl. listing failure), union tests updated,web/test/qa715.test.jsUI pins. CI green on PR #716 (1m16s).#717 — orphan folders: Take over and deactivate (v0.6.265, PR #718)
Follow-up to #715 from the same cleanup session: orphan rows offered only Details, because an orphan has no spacestore record and the lifecycle endpoints would 404.
What changed (UI only): the orphan row menu gains "Take over and deactivate" (danger item). It claims the folder through the normal
POST /api/v1/spaces(record owned by the acting admin; the dir already exists) and immediately runs the standard deactivate. From there it is a regular app-owned space: Reactivate, or the type-the-name Delete → contents to Deleted files, name tombstoned. IdP-verified managed rows stay Details-only.Verify (either dogfood, v0.6.265):
test5etc.) → "Take over and deactivate" → row becomesOwned by <you> · app-managed, Deactivated.Related: #719 filed for the keep-path ("Assign a new owner" dialog on orphan rows) — deliberately separate, low priority by construction.
Tests:
web/test/qa717.test.js; CI green on PR #718 (1m16s).