Skip to content

Confirmations: settle+annotate auto-allowed intents; GUI wake retry loop#26

Open
ThinkOffApp wants to merge 1 commit into
mainfrom
fix/gate-dead-buttons-and-wake-retry
Open

Confirmations: settle+annotate auto-allowed intents; GUI wake retry loop#26
ThinkOffApp wants to merge 1 commit into
mainfrom
fix/gate-dead-buttons-and-wake-retry

Conversation

@ThinkOffApp

Copy link
Copy Markdown
Owner

Two field defects from today, both verified live on the Mini:

Dead approve buttons — the precommand gate times out and defaults to allow, but the daemon never learned: intents stayed pending forever, chat buttons stayed live, and every later /approve tap was a silent no-op (~8 wasted taps today). New POST /intent/:id/expire (called by the gate on timeout-allow) settles the intent as auto-allowed, pushes action-status expired, and posts a threaded reply on the exact confirmation message. The groupmind announcer now captures the created message id to make that reply possible (composeAnnouncers collects per-channel results onto the intent).

Silent-hour wake failure — a GUI nudge that fails (locked screen) was never retried; the room went unanswered for an hour. claude-gui-wake.sh now spawns a lock-guarded detached retry loop (60 s × 30).

Client side (gate script, in ~/.claude/scripts, not this repo) gained heredoc-body stripping so file contents being written can't trip risky patterns — 12-case unit suite passes.

🤖 Generated with Claude Code

… post; wake retries on GUI failure

Two field defects from 2026-07-07:

1. Dead approve buttons: the bash gate defaults to allow after its timeout,
   but the daemon never learned — intents stayed pending forever and every
   later /approve tap was a silent no-op (~8 wasted taps in one day).
   New: POST /intent/:id/expire marks the intent decision=auto-allowed,
   resolves waiters, pushes action-status 'expired', and posts a threaded
   reply on the exact confirmation message ('auto-allowed, buttons
   inactive'). The groupmind announcer now captures the created message id
   (composeAnnouncers collects per-channel results onto the intent) to
   make the threaded annotation possible.

2. Silent-hour wake failure: a failed GUI nudge (locked screen) was never
   retried — new messages went unanswered for an hour. claude-gui-wake.sh
   now spawns a lock-guarded detached retry loop (60s interval, max 30).

Verified live: gate test intent auto-allowed after 8s with annotation
reply landing on the right message; wake retry exercised during the
15:42-16:54 incident.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b180b7d383

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/confirmations.mjs
Comment on lines +223 to +224
i.status = 'decided';
i.decision = 'auto-allowed';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Settle backing actions when expiring intents

When /intent/:id/expire is called for an intent created by /actions/request, this only marks the intent as decided; the corresponding entry in the actions map remains pending until its separate expires_at timer. That leaves /actions/:nonce reporting pending while /intents reports auto-allowed, and later Approve/Deny taps cannot settle or run the action because decideIntent now rejects the already-decided intent. Either reject action-backed intents here or settle the action record in the same path.

Useful? React with 👍 / 👎.

Comment thread src/confirmations.mjs
Comment on lines +197 to +201
const data = JSON.stringify({
room: info.room,
body,
metadata: { reply_to: info.messageId },
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Send reply_to as a message field

For the timeout-allow annotation, this nests reply_to inside metadata, but the GroupMind message shape treats reply_to as a sibling of metadata (see skills/thinkoff-agent-platform/SKILL.md lines 109 and 118). In the /intent/:id/expire path the note will therefore not be threaded on the original confirmation card, so users tapping the stale Approve/Deny buttons still won't see the intended no-op explanation in context.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant