Inspiration

SHIPGATE started with one question

Should an agent have access to a consequential action before the conditions for that action are satisfied?

Most agent systems expose tools continuously and rely on the model to decide when not to use them. I wanted to test a different model where trusted application state changes what the agent can actually do.

That became SHIPGATE.

Evidence becomes capability.

Instead of keeping deployment authority permanently available, SHIPGATE changes the browser's WebMCP tool surface as release evidence and human decisions change.


What SHIPGATE does

SHIPGATE turns release state into agent authority.

A release moves through four states

BLOCKED → REVIEW_REQUIRED → READY → SHIPPED

In BLOCKED, the agent can inspect evidence and request evaluation, but ship_release is not registered.

When the hard evidence passes, request_signoff becomes available.

The agent can request approval, but it cannot approve itself. Human confirmation stays outside WebMCP.

Only after human approval does the release become READY and ship_release appear as a registered WebMCP capability.

After shipping, that capability retires and temporary rollback_release authority appears.

Two rules shaped the project.

The agent can request evidence, but it cannot author the evidence.

The agent can request authority, but it cannot grant authority to itself.


Why WebMCP

WebMCP is the mechanism, not an interface added afterward.

SHIPGATE uses the browser's actual tool inventory to represent the agent's current authority.

  • BLOCKED → ship_release absent
  • REVIEW_REQUIRED → request_signoff available
  • READY → ship_release available
  • SHIPPED → ship_release retired and rollback_release available temporarily

This improves the experience for both sides.

People can see what authority the agent currently has and what evidence or human decision is still missing.

Agents do not need to reason over a deployment tool that should not yet be available.

The collaboration is explicit. The agent gathers evidence and asks for judgment. The human contributes authority the agent cannot give itself. The application turns those inputs into the capabilities that exist.


How I built it

The core architecture is:

trusted evidence → application state → capability → runtime recheck → verified effect

SHIPGATE is built with JavaScript, HTML, CSS, Node.js, Netlify, and native WebMCP.

Tools are registered through document.modelContext.registerTool().

Six tools remain permanently available for inspection and evaluation

  • get_release_state
  • get_release_policy
  • inspect_check
  • compare_to_baseline
  • list_evidence_gaps
  • run_check_group

Three capabilities appear only when the release contract allows them.

  • request_signoff during REVIEW_REQUIRED
  • ship_release during READY
  • rollback_release after SHIPPED while rollback remains valid

I also separated requesting evidence from creating evidence.

run_check_group lets the agent request an evaluation, but the agent cannot supply PASS or FAIL, choose the evidence source, change the candidate identity, or provide human confirmation. The evaluator owns the result.

Evidence is tied to the current candidate and its provenance. Stale or untrusted evidence cannot satisfy the release contract.

Human approval is deliberately outside WebMCP.

Tool availability also is not the security boundary. Consequential tools recheck the contract when invoked.

Tool availability narrows the action surface. Runtime validation remains the enforcement boundary.


Challenges I faced

Dynamic tool registration

The first challenge was making authority change safely at runtime.

ship_release needs to disappear when authority is lost and later return under the same name without duplicate registrations or race conditions.

I implemented a registration lifecycle.

HIDDEN → REGISTERING → ACTIVE → RETIRING → HIDDEN

SHIPGATE waits for registration or retirement to settle before the same capability can reappear.

A native Chrome race condition

The hardest bug appeared only during native WebMCP execution in Chrome 152.

ship_release could successfully move the release to SHIPPED, but immediate retirement of that tool could cancel the still-running executeTool() promise with an UnknownError.

The release had succeeded, but the browser call looked like it had failed.

I fixed this by separating policy authority from physical registration retirement.

The policy changes immediately, so another ship attempt already fails its runtime precondition. The browser registration retires only after the active invocation finishes.

That distinction made the native WebMCP lifecycle reliable.

Evidence authority

I also had to prevent the agent from creating the evidence that would unlock its own capability.

The solution was simple but important.

The agent can request an evaluation.

The evaluator decides the outcome.

That separation became one of the central design principles of SHIPGATE.


Testing

I tested both the application logic and the real browser capability surface.

SHIPGATE has 20 passing automated tests covering release transitions, evidence provenance, stale and untrusted evidence, human approval boundaries, runtime enforcement, conditional registration, same-name registration, and in-flight retirement.

I also tested the complete lifecycle in Chrome 152 using native document.modelContext WebMCP without mocks or stubs.

The browser confirmed the intended progression.

  • BLOCKED → ship_release absent
  • REVIEW_REQUIRED → request_signoff appears
  • pending approval → release does not advance
  • READY → ship_release appears
  • SHIPPED → ship_release retires and rollback_release appears
  • rollback → temporary rollback authority retires

For me, this was the important proof. SHIPGATE does not only change a button in the interface, but also changes the capability the browser exposes to the agent.


Demo candidate

SHIPGATE gates a real browser-game release candidate called FAKE LEFT.

FAKE LEFT provides the behavioral and regression evidence used in the demo release contract.

FAKE LEFT is the candidate being evaluated.

SHIPGATE is the system deciding which capabilities become available around that candidate.


What I learned

The biggest lesson was that agent judgment and agent authority are different product problems.

I began by thinking about whether an agent could correctly decide that a release was safe.

Building SHIPGATE changed the question.

Even if an agent can reason correctly, why should a consequential capability remain available before the surrounding evidence and human judgment are complete?

WebMCP let me make that distinction concrete.

The agent can inspect, evaluate, and request.

The human provides judgment the agent cannot give itself.

The application translates both into the authority that actually exists.

I think this pattern can extend beyond deployment to infrastructure changes, administrative actions, sensitive data access, financial operations, and other workflows where agent authority should follow trusted state.


What's next

The next step is connecting this capability model to real operational evidence.

The current demo uses deterministic evidence so every state transition is reproducible.

I would next connect SHIPGATE to CI pipelines, evaluation systems, production monitoring, approval workflows, deployment infrastructure, and rollback systems.

The long-term idea is straightforward.

Consequential agent capabilities should follow trusted real-world state rather than remain permanently exposed.

Built With

Share this project:

Updates

Submission history