8000 fix(approvals): only the person approves what the assistant asks by adeelahmad · Pull Request #598 · adeelahmad/lense · GitHub
[go: up one dir, main page]

Skip to content

fix(approvals): only the person approves what the assistant asks - #598

Merged
adeelahmad merged 1 commit into
mainfrom
claude/project-thread-xfmkzn
Oct 18, 2026
Merged

adeelahmad merged 1 commit into
mainfrom
claude/project-thread-xfmkzn

Conversation

@adeelahmad
Copy link
Copy Markdown
Owner

Requested by Adeel · project thread

Description

Before: the README says agents never approve, but an API key or an OAuth app could approve (or sample) the assistant's pending approvals, such as sending mail, adding an event or writing a file, through POST /api/v1/approvals/{id}. approvals.can and ai_tools.approve refused only the MCP/assistant route for approvals that weren't an automation's.

After: those approvals are approved only by the person signed in to Lens, or in the chat they were asked in, the same rule automation approvals already follow. Tokens, apps, MCP and the assistant can decline but get 403 on approve or sample, and can.approve says so. Research plans keep their existing admin switch (research.agents_skip_review).

How: approvals.can allows approve for the assistant's approvals only via "web" or "chat"; ai_tools.approve refuses a non-decline pick when can says no.

Motivation and Context

Found while building calendar proposals from dates said (personal feature plan sheet). The docs and threat model (P-APPROVAL) promised this; the code didn't enforce it.

Screenshots (if appropriate):

n/a

Steps to reproduce (if appropriate):

Ask the assistant to send a mail, then POST /api/v1/approvals/{id} with {"pick":"approve"} and an API key: before, it sent; now it's 403.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change; ! in the title)

Checklist:

  • The title is a Conventional Commit.
  • My code follows the code style of this project (make hooks checks it on commit).
  • I added or updated tests (test_approvals.py test_only_the_person_approves_what_the_assistant_asks, which fails on main).
  • My change requires documentation updates, and I have updated docs/ accordingly (automations, api, assistant, README, threat model).
  • Users need more than the title to understand it, so I wrote it under ## Unreleased in CHANGELOG.md. Written as changelog.d/agent-approve.md, per build(release): changelog fragments in changelog.d/ instead of one Unreleased section #581.

Done questions (AGENTS.md)

  • Goal: delivers what the user wanted, merged on green CI.
  • Agents: usable through the API, MCP or an assistant tool. Agents still decline through any route; approving stays with the person, as documented.
  • Zero setup: no new prerequisite, .env edit or manual step.
  • Fewest clicks and keystrokes. n/a: no UI change.
  • Configurable: new settings in the web app with defaults; wizard asks only what is required. n/a: no new setting.
  • Light: default install still runs on a Raspberry Pi with cloud models.
  • Private and secure: data local and encrypted, passkeys, threat model updated. Closes a gap in P-APPROVAL.
  • Cost: cheapest path, model calls in the activity ledger, budgets respected. n/a: no model calls.
  • User decides: consequential or new actions wait for the user; defaults unchanged. This is the change: only the user says yes.
  • Upgrades: existing installs upgrade safely (upgrade step for stored-data changes). n/a: no stored-data change.
  • Honest: sources cited; labelled built, in progress or planned.
  • Tests, docs and generated files updated. OpenAPI regenerated with the tooling (description only).
  • Open standards; dependencies keep Lens MIT. n/a: no dependencies.
  • Result reported with evidence; "refine later" items written down.
  • Reuse: existing Lens code and permissive libraries reused, nothing reinvented. Reuses the automation approvals' rule.

Local CI (ci/local-ci.sh): FastAPI (embedded and server), Next.js, pre-commit and PR title passed.


Generated by Claude Code

The assistant's approvals (send_mail, add_event, write_file, entity and
topic changes and the rest) could be approved through
POST /api/v1/approvals/{id} with an API token or an OAuth app token:
approvals.can only refused the "agent" route for approvals that weren't
an automation's. Now every assistant approval follows the automation
rule: only the person signed in to Lens, or in the chat it was asked in,
approves (or samples) it; an API key, an app, MCP and the assistant can
only decline (403 otherwise), and each approval's `can` says so. A
research plan keeps its admin opt-in, research.agents_skip_review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QFUNzy1QZy5HhKAyJxTAYJ
@adeelahmad adeelahmad self-assigned this Oct 18, 2026
@adeelahmad
adeelahmad merged commit 6047c8b into main Oct 18, 2026
12 checks passed
@adeelahmad
adeelahmad deleted the claude/project-thread-xfmkzn branch October 18, 2026 12:58
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.

2 participants

0