Short weekly notes on what actually shipped — newest first. No roadmap promises, just what changed and why.
A nudge is a moment, not a state
A report on October 15: five agent sessions working, and the companion showed "take a break" — never the agent status. The precedence was intended; a reminder you can't see is not a reminder. What was missing was an ending. An unanswered nudge had no expiry: the only ways out were the three bubble buttons, or locking the screen, which hands it to a system notification. Ignore it and it held the stage for as long as you stayed logged in, while real sessions went unreported behind it.
An ignored nudge now lapses after ten minutes and yields the companion back to agent status. Ten isn't a new number — it's the window a snooze already earns. If a reminder you deliberately postponed gets a second chance in ten minutes, one you ignored has had exactly as long to be acted on. The lapsed nudge closes its record honestly as skipped instead of staying pending out of sight. An agent that needs you still outranks a live nudge; that ordering was never the bug.
The window lives in a small policy type in PerchCore, with a deterministic test pinning both edges — holds at nine minutes, lapsed at ten — plus the case that matters most: a session waiting for input still wins. Shipped in 0.6.5-beta.1, build 22, on October 16.
That release almost didn't leave the machine. The signing preflight failed with "signing identity is not available in the keychain" while the certificate was valid — a doubled-prefix PERCH_SIGN_IDENTITY inherited from the calling shell matched nothing. The message pointed diagnosis at the slowest possible cause. Preflight now prints the requested value next to the keychain's actual Developer ID identities, and fails with a different message per side.
A zero-commit week — so this note explains a shipped behavior that rarely gets explained: what Sleepwing does when an agent goes quiet. Hook delivery is best-effort by design; it never blocks the host agent, which means signals can simply stop arriving.
If a "working" session produces no lifecycle event for 30 minutes, Sleepwing stops vouching for it. The task stays visible but flips to "No recent signal · status unconfirmed": the pet's aggregate mood stops counting it as active work, health timing and sleep protection pause, and nothing pretends to be done. The next real provider event clears the flag and the same task resumes in place; only a full two hours of silence removes it entirely.
The threshold is 30 minutes, not the original ten, for a concrete reason: providers report liveness per turn and per tool launch, so one long tool run — a full test suite, a slow model call — is silent the whole time it works. Ten minutes cut those off mid-run and told you your agent had stopped while it was still going. The state machine lives in a deterministic reducer in PerchCore, with unit tests pinning both edges of the threshold and the resume path.
This week handed us the same lesson on the ops side: our own metrics cron turned out to have been down for 17 days (September 23 – October 9), discovered only at weekly review. Fail-closed logs nobody reads are just silent failures with a paper trail. A stopped signal should be loudly unconfirmed — in the product, and in the pipeline that builds it.
Two beta builds went out this week — 0.6.1 (build 18) and 0.6.2 (build 19) — and both exist for one feature: clicking a waiting task now lands on the exact terminal tab hosting that agent session, not just the right app. If you run a dozen tabs across iTerm and Terminal.app, "Codex is waiting for you" used to mean tab-hunting. Now the hook records the session's controlling-TTY device name (never contents, never paths), it travels as an allowlisted local resume route, and the click selects that specific tab. Unscriptable terminals keep the activate-the-app fallback, and any known terminal — Ghostty, kitty, Alacritty, WezTerm — is now eligible for recall, not just a hardcoded three.
Build 19 exists because of a genuinely annoying macOS detail: the relay first asked ttyname() about an opened /dev/tty, and macOS answers with the alias itself — literally "/dev/tty" — which routes nowhere. The fix reads the process's own e_tdev from sysctl's kinfo_proc and resolves it with devname(), which yields the real device the tab owns.
Also shipped: a proactive warning when a previously-working hook disappears from a host's config (rescanned about once a minute), so an integration can no longer die silently, and the pet now yields full-screen Spaces until an agent actually needs you.
The notarized 0.6.0 build 17 went out on GitHub Releases this week — Sleepwing's first public beta, signed with a Developer ID and stapled, macOS 14+ on Apple Silicon. The release script fails closed: if notarization doesn't come back clean, nothing ships.
The most satisfying fix was small: the completion celebration used to sprint through its frames in 1.8 seconds and read as fast-forward next to its caption. The frames now hold roughly twice as long, so the same arc lasts about three seconds, and the celebration window, the caption, and the onboarding demo pacing all derive from one constant so they can't drift apart again. A related fix keys the celebration to the on-model landing frames instead of firing mid-air.
The site also grew four SEO pages — an honest comparison, an agent-notifications guide, a TRAE user guide, and the community pet gallery — wired into a sitemap and an IndexNow submission pipeline so search engines hear about changes the same day. One embarrassing bug closed out the week: the social share card rendered CJK text in a fallback font. Fixed.