Skip to content

feat(crew): approve once needs the person's click in the desktop app - #533

Open
kinqsradio wants to merge 2 commits into
mainfrom
feat/crew-presence-core
Open

kinqsradio wants to merge 2 commits into
mainfrom
feat/crew-presence-core

Conversation

@kinqsradio

@kinqsradio kinqsradio commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Approve-once now needs a one-time grant the desktop shell records after the person clicks Approve in its native dialog; the account's confirmation, CONFIRM_PREFIX, the account_disabled branch and the stand-in guard are gone from it.
  • Core half only: presence_describe / presence_grant on the shell channel, answered presence_hold / presence_ready / presence_refused; new in-memory PresenceBook (one grant per hold, 60 s, replaced by a later grant, used once, --parent-stdin only).
  • New errors: 403 desktop_required (no shell, or remote), 403 presence_required (missing, wrong, used, expired or mismatched nonce; a refusal never burns the grant).
  • Not built: the shell dialog (PR2) and the web card (PR3). Until then nothing mints a grant, so approve-once answers presence_required or desktop_required.
  • presence_hold text is made plain: newlines become a visible ⏎, control, invisible and bidi characters a visible �, the command is capped at 1000 characters with truncated. PR2's dialog must render it as plain text.
  • Docs state the claim and its limits: no caller that only speaks HTTP to the service can approve once, with or without the service token; this is not OS-level presence.

Refs #532

Parity rows

none

Frames built

Frames built: none

Testing

  • CI covers the rest.
  • Local: fmt, clippy --workspace --all-targets -D warnings, orbyn-core crew/host/account tests, orbynd unit tests, presence_stdio against the real binary, check_rust_arch.py.
  • Also: two approvals racing with one nonce on separate threads give one success.
  • Not tested: the real shell and Windows; the 60 s expiry only through the injected clock.

Co-authors

none

AI usage

  • Written by hand, with no AI
  • Harness and version: Claude Code 2.1.321
  • Models: claude-sonnet-5-5 (implementation)
  • Effort: medium
  • Human role: assigned the task and its boundaries; review pending
  • Sources: none

Checklist

  • Works on Windows and macOS
  • web/src/generated with any contract change; docs/architecture.md with any rule change
  • No copied source, secrets, credentials or personal data; no AI attribution in commits, title or branch

The core half of local presence: the shell describes a hold and grants a one-time nonce over the parent channel, PresenceBook keeps one grant per hold for 60 seconds, and approve-once takes it instead of the account's confirmation. Nothing mints a grant until the shell dialog (next PR) exists.
@github-actions github-actions Bot added area: core crates/orbyn-core: runs, drivers, workspace, approvals, storage area: service crates/orbynd: local service and CLI area: docs docs and Markdown files labels Nov 12, 2026
)
.await
.unwrap()
const NONCE: &str = "0123456789abcdef0123456789abcdef";
let (w, id) = held_world().await;
let hold = hold_of(&w, &id, "make deploy").await;
let first = grant_for(&w, &hold);
let second = grant_at(&w, &hold, "fedcba9876543210fedcba9876543210", unix_now());
mod tests {
use super::*;

const NONCE: &str = "0123456789abcdef0123456789abcdef";
let live = 100 + PRESENCE_LIFETIME_SECS - 1;
assert!(book.confirmed_for(&what("h-1"), Some(NONCE), live));
assert!(!book.confirmed_for(&what("h-1"), Some(NONCE), live + 1));
let second = "fedcba9876543210fedcba9876543210";
fn password() -> String {
["correct", "horse", "battery"].join(" ")
}
const NONCE: &str = "0123456789abcdef0123456789abcdef";
let (status, body) = app.call("POST", &path, json!({}), Some(NONCE)).await;
assert_eq!((status, &body["code"]), (403, &json!("presence_required")));
let (_, other) = app.held("b", "make ship");
let for_other = app.grant(&other, "fedcba9876543210fedcba9876543210");
presence_hold strings lose newlines and invisible or bidi characters (visible marks), the command says if it was cut, stale account-flow comments go, and two approvals with one nonce have one winner.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: core crates/orbyn-core: runs, drivers, workspace, approvals, storage area: docs docs and Markdown files area: service crates/orbynd: local service and CLI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants