Skip to content

Honest Actions: confirmation + receipts for simulated actions#8

Draft
Vext-Labs wants to merge 6 commits into
thesysdev:mainfrom
Vext-Labs:agent/feat-honest-actions
Draft

Honest Actions: confirmation + receipts for simulated actions#8
Vext-Labs wants to merge 6 commits into
thesysdev:mainfrom
Vext-Labs:agent/feat-honest-actions

Conversation

@Vext-Labs

Copy link
Copy Markdown

Draft: stacked on #7 — this branch includes those commits and will be rebased once it lands. Opened for early feedback on the approach.

What

AppLess's README is admirably honest that generated actions are simulated — "order placed", "flight booked", "payment sent" do nothing. This PR adds an Honest Actions layer that makes that simulation explicit in the product, and makes the future real integrations (the README's DoorDash / Plaid / Spotify ideas) pluggable:

  • Risk tiers (src/genos/actions/model.ts) — navigation/read actions auto-execute as today. Consequential actions (order/book/pay/send/delete-shaped, classified by a small documented heuristic) pause on a confirmation sheet that says exactly what will happen: "AppLess will simulate this. Nothing real is charged or booked."
  • Receipts (actions/receipts.ts) — every consequential action produces a durable receipt (confirmed-simulated / declined), so the UI has an honest, inspectable record of what the OS "did".
  • Executor registry (actions/executor.ts) — a default SimulatedExecutor plus registerExecutor(), so a real integration can swap in per action kind without touching the shell. Executors only ever run from an explicit post-confirmation tap — never from prefetch/speculative paths (tested).

This maps directly onto the maturity items in your agentic-interface-framework writeup: approvals (D19/D20) and rollback/inspectability (D34) — AppLess currently fails its own authors' test on those items, and this is a small step toward passing it.

Honest limits

Actions are still simulated — this is the honesty layer, not real integrations. Typed ask-bar commands intentionally bypass the sheet (explicit user intent). Documented in docs/honest-actions.md.

Test plan

  • npm run typecheck
  • npm test — 40 passed (22 existing + 12 security + 6 actions) ✓

Contributed by Vext Labs.

New src/genos/safety modules enforcing at runtime what the system prompt
can only request:
- urlPolicy: only http(s) links reach Linking; every other scheme blocked
- genosLink: genos://open targets validated (catalog ids or safe slug
  shape), requests capped at 300 chars, toast text at 120
- redaction: credential-shaped form values replaced with [redacted]
- tools/images: model-supplied image URLs resolve only on allowlisted
  https hosts, else fall back to the LoremFlickr semantic path
- GenOS.handleAction routes external URLs through openExternalUrl with a
  blocked-link toast, and genos:// links through parseOpenLink/capToastText
- store.resolveAction redacts credential-shaped form values before they
  are sent to the provider or replayed as context; openDeepLink re-caps
  the injected request (defense in depth)
- KeyGate masks the API-key entry field (secureTextEntry)
- media.tsx documents that raw URLs pass the image-host policy first
12 tests covering the scheme allowlist (javascript:/intent:/sms:/etc
blocked), deep-link caps and app-id validation, password redaction into
the provider request, and the image-host policy with its LoremFlickr
fallback. SECURITY.md adds a reporting policy plus honest hardening
notes and limits.
Honest Actions foundation: classifyAction splits model-declared actions
into auto (navigation/read) vs consequential (order/pay/send/delete-
shaped, whole-word heuristic); a KeyStore-shaped receipt log records
confirmed-simulated and declined outcomes; a pluggable executor registry
ships a default SimulatedExecutor that says so honestly, with
registerExecutor() as the seam for the README's real integrations.
Executors never run from prefetch/speculative paths.
Consequential taps pause on a sheet stating exactly what will happen
('AppLess will simulate this action. Nothing real is charged or
booked.'). Confirm runs the executor, receipts the action, shows the
honest outcome toast, and proceeds; Cancel records a declined receipt
and does nothing else. Total GenOS diff across both passes: ~104 lines.
6 tests: classification both directions, receipt record/decline ordering,
default executor honesty, registry swap/restore, and the no-prefetch
invariant (spy executor survives speculative prefetch untouched).
docs/honest-actions.md covers the tier model, registry API, the
D19/D20/D34 mapping, and honest limits.
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