Honest Actions: confirmation + receipts for simulated actions#8
Draft
Vext-Labs wants to merge 6 commits into
Draft
Honest Actions: confirmation + receipts for simulated actions#8Vext-Labs wants to merge 6 commits into
Vext-Labs wants to merge 6 commits into
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
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."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".actions/executor.ts) — a defaultSimulatedExecutorplusregisterExecutor(), 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.