Ceiling

Why I built it

Agents are getting better at working inside websites. That is useful, but it creates a basic problem: how do I let an agent help without handing it every action available in my signed-in session?

Ceiling is my attempt to answer that question with something people can actually try. It is a small release-policy workbench where an agent can read the current state, prepare a change, and explain why it wants that change. The page decides whether the request fits its rules, and a person remains in control of the final action.

I did not want the safety story to be a warning banner or a promise in a README. I wanted the boundary to be visible in the interface and testable from the agent side.

What it does

The demo follows four simple steps:

  1. The agent proposes one change.
  2. Ceiling checks the value and shows the difference.
  3. A person can authorize that specific change for a few seconds.
  4. The page applies or rejects it once and records what happened.

Unsafe requests stop before the approval step. In the demo, an attempt to turn off signed artifacts is denied immediately. A safer request to change the rollback window from 30 to 45 minutes is allowed into review, but the agent still cannot apply it on its own.

Approval is deliberately narrow. It is tied to the current policy, the proposed value, and the requested operation. It expires quickly and cannot be reused. Rollback follows the same rule instead of acting as an unprotected escape hatch.

Every decision adds a linked receipt. The page can verify the chain again and export the session evidence as JSON. A built-in Defense Matrix also tries seven ways to break the boundary, including replay, expiry, parallel application, and receipt tampering.

Why WebMCP fits

Without a structured interface, an agent either has to guess from pixels or a site has to expose a broad action API. WebMCP gives the page a better option: it can publish a small, discoverable set of tools with clear inputs.

Ceiling registers 11 tools directly through document.modelContext.registerTool(). Four are read-only. Seven cover the review workflow. An agent can inspect the available tools, read the policy, propose a change, test the safety boundary, and verify the receipts without being given deployment, credential, payment, messaging, or cross-origin powers.

The result is a better experience for both sides. The agent does not have to guess what it is allowed to do, and the user does not have to trust a vague confirmation dialog.

How I built it

Ceiling is dependency-free HTML, CSS, and JavaScript. The WebMCP tools use closed input schemas, and the interface reports whether registration succeeded, partly succeeded, or is unavailable.

The release-policy demo sits on a reusable scalar-change core. I also tested that core against publishing, access-control, and spending-policy examples to make sure the pattern was not tied to one screen.

The focused suite currently includes 78 tests, a 23-case policy evaluation, and 50 cross-domain adapter checks. I used OpenAI Codex during implementation, testing, adversarial review, and release packaging. A separate non-author review initially rejected the release because of three packaging and claim-boundary problems. I corrected those problems before preparing this submission.

What was difficult

The hardest part was defining what a click actually proves. Browser automation can produce trusted input, so Ceiling does not call a click proof of identity or proof that no automation was involved. It treats the gesture as short-lived permission for one visible operation and no more.

I also found a concurrency bug in an earlier receipt implementation. Parallel writes could reuse the same sequence information. I kept that behavior as a regression fixture, serialized the active write path, and added full-chain verification.

Chrome on my test machine did not expose WebMCP during the recorded fallback pass. The page says that plainly and keeps the fallback controls separate. The working WebMCP demonstration was verified in the ChatGPT/Codex in-app browser.

What I learned

The most useful lesson was that refusal is part of the product. A trustworthy agent interface should make denied actions, missing capabilities, and failed preconditions as clear as successful ones.

I also learned that evidence is only useful when it is easy to inspect and hard to accidentally overstate. The final project deliberately claims less than the larger system I hope to build.

What's next

Ceiling is session-local by design. The next steps would be reviewed host adapters, optional signed or externally anchored receipts, and carefully scoped persistence. Each would need its own authority boundary rather than silently expanding the one demonstrated here.

Built With

Share this project:

Updates

Submission history