* fix(daemon): take a foreign device claim the device's own reboot invalidated
An open that found a claim belonging to another session gave up even when
the device had rebooted since that claim was taken, leaving the surface
unreachable for every session. A reboot already took the app and the runner
away, so the claim guarded nothing.
Ask the device when its current boot began and release a foreign claim whose
stamp predates it. The stamp is the last instant the owner vouched for the
device, renewed by every open that reaches it, including the one that boots
the device on the way in, so an owner that boots the device for its own work
keeps it and only an owner that never came back loses it.
Co-Authored-By: Claude <noreply@anthropic.com>
* chore(gates): classify the daemon edge that asks a device when it booted
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* docs+ux: make device ownership discoverable end to end
Complete the #1320 agent experience so 'busy? -> inspect -> choose or
release' is discoverable from every surface an agent actually reads:
- devices now projects the blocking claim owner per row (claimedBy with
session and workspace, observe-policy projection; provably dead owners are
excluded because the next open replaces them automatically), so an agent
told a device is busy can pick a free one from the same listing.
- help debugging gains a 'Device busy and ownership' section separating the
two DEVICE_IN_USE flavors and their exact recoveries.
- AGENTS.md documents both flavors; docs/agents/device-verification.md
retires the last ps/kill recovery guidance in favor of device status,
daemon stop --state-dir, and device release --stale (Stage 5 of #1320).
- ADR-0010 no longer calls DEVICE_IN_USE 'the only retriable code' without
naming the claim path's non-retriable override.
- The rendered cross-worktree claim error gains a help-conformance quiz case
binding (sample-output-device-claim-inspects-owner).
- README points at device status / device release --stale.
Part of #1320.
* fix: key ownership projection by canonical device identity end to end
Review findings on #2165:
- blockingClaimOwnersByDevice keyed claims and inventory rows by bare
device.id, so a live Android claim could project claimedBy onto an
unrelated same-id Apple/Harmony/Vega row, with scan order picking the
displayed owner. Both sides now use the canonical local device key
(claim.deviceKey against canonicalLocalDeviceKey of the row's claim
identity). The cross-family same-id regression was observed red against
the bare-id keying.
- The projection is now asserted across every hop the PR promises: client
normalization preserves well-formed claimedBy and drops malformed ones,
and the devices CLI formatter carries it through JSON data and renders
the text line (MCP shares the same serialization).
* docs: restructure AGENTS.md and CONTEXT.md for progressive disclosure
Apply the Claude 5 context-engineering guidance to the repo's agent docs:
keep the always-loaded file to gotchas and invariants, and move situational
guidance one hop away behind a routing table.
AGENTS.md 315 -> 229 lines. Cut generic agent-behavior boilerplate, three-way
duplication (Common Mistakes restated Hard Rules; Finding Source Owners
restated the registry section), and facts visible from the repo itself.
Kept verbatim: the expensive-lessons principles, enforcement gates, Hard
Rules, and environment traps.
Split out docs/agents/{cli-flags,pull-requests,device-verification}.md and
folded the Testing Matrix into docs/agents/testing.md, reframed around
pnpm check:affected so the prose stops duplicating the selector.
CONTEXT.md keeps all 50 terms, now grouped under a section index so a task
loads one section instead of the whole glossary.
* fix(check-affected): move the selector-owning sentinel to the Testing Matrix
The Testing Matrix moved from AGENTS.md to docs/agents/testing.md, but the
affected-check selector still treated only AGENTS.md as selector-owning. A
later matrix edit would have been classified as inert docs and skipped the
fail-open, so the selector could keep deriving gates from a spec that had
changed underneath it.
Move the sentinel with the prose, as a named SELECTOR_OWNING_DOCS set so the
next move is one line, and fix the two in-code comments plus the testing.md
paragraph that still pointed at the AGENTS.md matrix.
* docs: restore two rules dropped by the AGENTS.md split
Review caught two repo-specific rules that did not survive the move. Both are
prose without any backticked identifier, so the identifier-diff used to verify
the split could not see them.
- "Test through public interfaces; do not add unrelated production exports
solely to enable tests" returns next to the behavioral-tests rule in
docs/agents/testing.md, with the reason it exists.
- The guidance-ownership rule (decide whether new guidance/schema/metadata
belongs to the command surface, CLI grammar, CLI help, MCP projection, or
daemon runtime) returns to the always-loaded Docs & skills section, since it
governs all command-surface work and not just the flag case.
Also point the ADR routing row at docs/adr/README.md, which is already the
"read when you touch…" index, rather than at the bare directory.