Skip to content

guardrails in plain english + a gui; no posting command — the browser, navigated like a person - #59

Merged
huyedits merged 5 commits into
mainfrom
symbio-pet
Sep 27, 2026
Merged

huyedits merged 5 commits into
mainfrom
symbio-pet

Conversation

@huyedits

@huyedits huyedits commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

Why

Asked to post make a tweet “testing" on x.com, the agent typed "Hi" into the composer and clicked Post. It used browser_type and browser_click, neither of which asked for approval, so "Hi" went out publicly under the user's name. The user also found safety.py too rigid. After review, the user ruled out any site-specific shortcut: no tweet-to-X command; the model has to learn to use the browser itself.

What changed

No posting command. post_to_x, its aliases, the forced quoted-tweet route, and every x.com-specific selector and rule are removed. Symbio now posts the way a person would:

  1. open the page;
  2. type into the box, addressed by its CSS selector;
  3. click the button next to the box;
  4. read the page back.

Browser navigation, the same on every site

  • After opening a page, or after a click that changes it, the result lists the page's text boxes (with their selectors) and the buttons that send them. Post / Reply / Send buttons are listed before navigation links, and a button shows as [disabled] until its box has text. Before, this list only appeared after a step failed.
  • When the user quoted words (“testing”) and the model types something else, the result says so.
  • browser_click given x/y coordinates is handled as a click at that point.
  • A failed browser step repeats the user's request in its result, so the model does not drift back to an earlier turn's task.
  • One reply can chain up to three page steps, such as typing and then clicking, instead of one step per model round.
  • Words in curly (“smart”) quotes now count as something the turn must do. If no tool output mentions them, the turn is asked to finish instead of stopping at "I've opened X".
  • The model that decides how to handle each message now has examples of website actions: reply, comment, post, fill in a form. These now go to the action route (no reasoning pass, which cost 60 s per round) instead of falling through to a pattern match.

Guardrails, by kind of action and in plain English

  • There are 9 kinds, including Post or send, Run commands and code, and Change files. Each can be set to Allow, If risky, Ask, or Never. The defaults behave the same as before.
  • Each action asks one question. The card's headline is the model's own sentence about the action, and below it is the exact text or command.
  • "Post or send" is detected on any site: a Post/Reply/Send/Comment/Submit button next to a box with text in it, cmd+enter in a multi-line box, or Enter in a chat box that has a Send button. Search boxes and login forms don't count. If the words about to go out aren't the ones the user quoted, the card shows a red warning.
  • Always allow still asks before anything destructive. When the user picks Never, the model is told the refusal came from the user.

Desktop window

  • Approval cards have Allow, Always allow, and Deny buttons. A card is sent again if the window reloads.
  • Settings has a Guardrails section, backed by /api/guardrails.
  • The server now rejects requests from any other web origin. Before this, any web page could open the chat socket or write settings.

Look (/avoid-ai-design)

  • The window's colours now come from the tilcayo icon instead of Claude's palette.
  • SF Rounded is used for Symbio's name, headings, and card headlines.
  • Removed all-caps labels, monospace used as decoration, middle-dot separators, emoji icons, and the blurred modal backdrop.
  • Muted text meets WCAG AA contrast. Added keyboard focus rings and reduced-motion support.
  • Rules are in symbio_desktop/DESIGN.md.

Verified

  • Full suite: 2772 passed, 5 failed. The same 5 fail on the base commit and are unrelated: test_thinking_alignment, 2 × test_install_layout, test_rag (subprocess environment), and the test_dispatch refusal test (browser tool group not enabled in the test config).
  • Headless Chromium, two fake sites built nothing alike (an X-like page, and a forum using a <form>, a textarea, and a Reply button): 12/12 checks.
    • The sidebar's Post link, a search box's Go button, and Enter in a post box are not treated as sends.
    • Post/Reply clicks and cmd+enter are asked about, with the text shown.
    • "No" blocks the send; "yes" posts.
  • Real 14B on the same fake sites, using only the ordinary browser tools, with every card approved:
    • Reply “testing” on the forum: posted exactly testing in 50 s.
    • Tweet “testing”: posted exactly testing in 73 s.
    • Tweet “gm everyone”: posted exactly that in 44 s.
    • In an earlier run, the X turn stopped after opening the page, and the smart-quote check sent it back to finish.

huyedits and others added 2 commits September 27, 2026 15:04
…lick is judged by what it lands on: pressing X's post button (by text, coords or cmd+enter) asks u first w the words in the box, and says so in red when they're not what u asked for. every question is one card w caine's own sentence + the exact post/command, per-kind allow/if risky/ask/never in settings, "always allow" on the card. "make a tweet “testing"" posts exactly that via post_to_x (clears the box, proves a NEW post). window server only talks to the window now (any web page could open the chat socket before). and the window stopped being a claude clone: colours from tilcayo's icon, pond teal + tabby ink + the charm's amber >//<

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ryuzz9EtCjeeR8ofVxhGW
…ly bit. caine posts like a person now: open the page, type into the box by its selector, click the button beside it, read it back. the page hands over its boxes + send buttons (not just after a fail), words u didn't ask for get pointed out, a click w x/y is a click_at, a failed step carries ur request so it doesn't wander off to the last task, a reply can chain type+click, and “smart quotes” count as things the turn has to do. the send guardrail is site-neutral: any post/reply/send button next to a filled box asks first. tested live on the 14B: fake x.com AND a fake forum built nothing alike, 3/3 posted exactly what was asked :3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ryuzz9EtCjeeR8ofVxhGW
@huyedits huyedits changed the title guardrails in plain english + a gui for them; x.com posts only what you asked guardrails in plain english + a gui; no posting command — the browser, navigated like a person Sep 27, 2026
huyedits and others added 3 commits September 27, 2026 21:14
…t forgets our json, and nothing read it, so every call it made that way just vanished T_T parse_tools reads the native form now, json form untouched, prose that only mentions function= isn't a call :3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ryuzz9EtCjeeR8ofVxhGW
…rch saw "about" + a number, googled the user's own disk, and swapped the answer for "couldn't find it in the search results" T_T a hedged figure that rounds from something a tool printed this turn isn't a guess anymore :P

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ryuzz9EtCjeeR8ofVxhGW
…yers can't be rewound, so any change to the prompt rebuilt the whole 6.5k-token cache from zero T_T a cache like that now keeps copies where the next prompt picks up (end of the system prefix, where the newest user message starts, end of the last message) and restarts from the longest one. same tokens as the live cache on a real hybrid model, 14B path untouched :3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ryuzz9EtCjeeR8ofVxhGW
@huyedits
huyedits marked this pull request as ready for review September 27, 2026 22:58
@huyedits
huyedits merged commit e8ea39e into main Sep 27, 2026
0 of 2 checks passed
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