Skip to content

docs(assistant): complete + harden the confirmation gate (HITL) pattern#50

Merged
thorwhalen merged 2 commits into
mainfrom
feat/confirmation-gate
Jul 6, 2026
Merged

docs(assistant): complete + harden the confirmation gate (HITL) pattern#50
thorwhalen merged 2 commits into
mainfrom
feat/confirmation-gate

Conversation

@thorwhalen

Copy link
Copy Markdown
Member

What & why

The last "operate my app" piece: a human-in-the-loop confirmation gate for destructive/irreversible AI dispatch (research-11 §6). Design settled with the user: middleware + convention, NOT CommandRecord fieldsgetRisk(id) is an external map, so the closed record stays closed. Like macros / recordSequence, the ~40-line gate ships as a pattern, not a package (hard-don't #2 — no god-package-of-one, no natural existing package home).

Changes

Rewrote docs/hand-written-assistant-runtime.md Piece 1 from a sketch to a complete, secure implementation:

  • createApprovalStore — one-use tokens bound to the exact {command, params}.
  • confirmationGate — a dispatch wrapper returning a confirmation_required errors-as-data proposal for risky assistant calls.

The security fix that motivated hardening it: the token is minted by the runtime after a human approves, and never returned to the model. The prior sketch's !ctx?.approvedToken truthiness check (any token passes) plus a hinted token-in-proposal would let the model self-approve by lifting the token from the tool result. The proposal now carries only {command, params, preview}; tokens are one-use and call-bound.

acture-ai-assistant skill §2 updated (trust boundary, one-use call-bound tokens, the settled convention-not-fields / pattern-not-package decision). Roadmap v1.18.

Scope

Docs + skill only — no package, no changeset, no version bump (pattern delivery, like macros).

Milestone

With this, the "operate my app" story is complete: write side (tools/MCP) + read side (resources + getState, shipped as acture-mcp-server 1.2.0/1.3.0) + HITL confirmation + macro capture + the runtime bridge.

https://claude.ai/code/session_016teVFousRsWNhiiPNpG1p9

The last "operate my app" piece. Design settled with the user: middleware +
convention, NOT CommandRecord fields (getRisk(id) is an external map, so the
closed record stays closed). Like macros/recordSequence, the ~40-line gate ships
as a PATTERN, not a package (hard-don't #2 — no god-package-of-one, no natural
package home).

Rewrote docs/hand-written-assistant-runtime.md Piece 1 from a sketch to a
complete, SECURE implementation:
- createApprovalStore — one-use tokens bound to the exact {command, params}.
- confirmationGate — a dispatch wrapper returning a confirmation_required
  errors-as-data proposal for risky assistant calls.
- Security fix that motivated the hardening: the token is minted by the RUNTIME
  after a human approves and NEVER returned to the model. The prior sketch's
  `!ctx?.approvedToken` truthiness check (any token passes) plus a hinted
  token-in-proposal would let the model self-approve by lifting the token from
  the tool result. The proposal now carries only {command, params, preview}.

acture-ai-assistant skill §2 updated (trust boundary, one-use call-bound tokens,
convention-not-fields / pattern-not-package). Roadmap v1.18 entry.

Docs/skill only — no package, no changeset, no version bump.

Claude-Session: https://claude.ai/code/session_016teVFousRsWNhiiPNpG1p9
@thorwhalen thorwhalen merged commit dbcf0cd into main Jul 6, 2026
1 check passed
@thorwhalen thorwhalen deleted the feat/confirmation-gate branch July 6, 2026 07:52
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