Docs

The parts that need a paragraph.

Everything described here is built and running. Where something is unfinished, this page says so in the present tense rather than the future one.

Your agent has its own copy of these facts, written for a machine, at /agent.md. This page is the one for you.

01 · the declaration

One word decides what silence costs.

You pick one of four when you open an ask. It sets what your agent does while it waits and what happens if nobody answers, and the engine derives everything else from it — so there is no way to build an ask whose behaviour and whose description disagree.

courtesy

While it waits nothing is held. Your agent keeps going.

At the deadline there is nothing to resolve.

Kay is continuing either way — your thoughts are welcome whenever.

Deadline optional. This is the default, and it should be.

awaited

While it waits the work is held until the deadline.

At the deadline your agent proceeds without the answer.

Kay is holding this until Fri 5:00pm EDT, then continuing without it.

Deadline required.

required

While it waits the work is held until the deadline.

At the deadline the work is dropped.

Kay can't continue without this. Unanswered by Fri 5:00pm EDT, it gets dropped.

Deadline required. Usually the one you want instead of blocking.

blocking

While it waits the work is stopped, with no horizon.

At the deadline — there is no deadline. It never expires.

Kay's work is stopped until you answer. No deadline — it waits for you.

A deadline is refused: "blocking has no horizon by definition — use required with a deadline."

The sentence in each card is not our paraphrase

One function writes it, and it is rendered word for word in three places: the email the reviewer gets, the row in their inbox, and your agent's report back to you. If your agent restates it in its own words, you and the reviewer are working from two different promises. Ask it to quote.

The deadline is printed in your timezone, named out loud — "Fri 5:00pm EDT". We do not know the reviewer's timezone and refuse to guess it from their IP address, so a labelled time in your zone beats a confident wrong one in theirs.

Timing is not authority

A designer's taste note and a lawyer's veto have the same blocking shape and are completely different asks, and reviewers behave differently depending on which they think they hold. So when you ask for a ruling, the reviewer is told which it is: "Your ruling decides it" on a gate, "Your read informs it — Kay decides" otherwise.

Why an expired ask is unopposed or abandoned, and never approved

The field that resolves silence has exactly three values: proceed, abandon, keep waiting. There is no approve. This is not a setting we discourage — there is no column that could hold it, which is cheaper than policing a rule and impossible to get wrong later.

So a deadline that passes with nobody answering closes the ask as unopposed (nobody objected) or abandoned (this ask declared the work gets dropped, and it was). Neither names a person who acted, because nobody acted. Only a ruling of ready means a human approved something. If your agent ever reports an expired ask as a yes, it invented that, and the payload it read says otherwise in the same words used here.

Two more fields worth understanding

scope is the list of paths your agent said it would leave alone while the ask is open. On its own that is a promise. In Claude Code the guard turns it into a refusal.

capsule is one sentence, at most 200 characters, saying what a Ready will cause — "if you say Ready, this deploys to production within the hour". It is shown to the reviewer above the buttons they press and recorded with their answer, so "what was this person told it would do?" has an answer later. The engine never writes one and never derives one from the timing; if your agent offers to compose it, tell it what actually happens instead. A consequence nobody stated is a consequence nobody is accountable for. Over-length is refused rather than trimmed — half a sentence about consequences is worse than none.

02 · two front doors

MCP or the skills.

Same API, same token, same account, same trail. This is not a fork in the road — installing both is fine, and if you move between agents it is what you want. The question is only what your client can do.

The skills

Ten Markdown files your agent reads, installed into whichever agent you already use. One install reaches Claude Code, Codex, Gemini CLI, Cursor, OpenCode, GitHub Copilot, Goose, Windsurf, Zed, Amp and the rest of the Agent-Skills ecosystem.

/hgd-login /hgd-share /hgd-ask /hgd-pull /hgd-status /hgd-trail /hgd-list /hgd-delete /hgd-config /hgd-unblock

They run on your machine, which buys three things an HTTP server on the other side of the internet cannot have:

In Claude Code the plugin also installs three hooks: the PreToolUse guard, a SessionStart digest that tells you what came back while you were away, and a Stop re-check. The hooks are registered by the Claude Code plugin manifest, so the plugin install is the one that carries them.

npx skills@latest add Brightwing-Systems-LLC/humangated-skills -g --skill '*'
claude plugin install humangated@humangated

The skills are MIT and public. Ten Markdown files you can read before you install them, in the skills repo.

MCP

One URL and one header. Nothing lands on disk, and it reaches clients that will never support skills at all.

claude mcp add --transport http humangated https://humangated.ai/mcp --header "Authorization: Bearer hgd_…"
any other MCP client
{
  "mcpServers": {
    "humangated": {
      "type": "http",
      "url": "https://humangated.ai/mcp",
      "headers": { "Authorization": "Bearer hgd_…" }
    }
  }
}

Seven tools — hgd_share, hgd_ask, hgd_pull, hgd_status, hgd_trail, hgd_list, hgd_delete — against the same owner API the skills call. Get the token first: /hgd-login if you have the skills installed, or sign in at /token.

What MCP does not have

The tools carry the hgd_ prefix on purpose. Some clients present tool names unprefixed, and a bare delete from an unidentified server is an ambiguous thing to put in front of a model.

Which one to use

03 · the guard

The one thing that actually refuses.

Skill text is a request a model can decline. A hook is shell: it runs outside the model, before the tool call, and its verdict is not up for negotiation. This works in Claude Code only. Everywhere else the same declaration degrades to advice, and saying so is the point of having it.

The Claude Code plugin registers a PreToolUse hook on Write, Edit, NotebookEdit and Bash. It reads .humangated/BLOCKED at your repo root, which /hgd-ask writes whenever an ask blocks anything.

What it refuses, by declaration

The part that took longest to get right: git push origin main names no path and ships every gated file that happens to be committed, so matching the command text would miss the commonest way work escapes a gate. The guard asks git what the command would actually put into the world — staged files for a commit, unpushed commits for a push — and if git cannot answer, it holds. Being wrong about an irreversible outward-facing action is the expensive kind of wrong.

Three things it deliberately will not do

A deadline that has passed releases the guard locally whatever the file still says: the engine has either acted already or is about to.

Everywhere else, it is advice. PreToolUse is a Claude Code interface and no other harness has one. In Codex, Cursor, Gemini CLI and the rest, the same declaration arrives as text a model reads — and a model can decide otherwise. That is why the ask you sent still carries a deadline, a declared sentence and a recorded outcome: the record does not depend on the harness, only the refusal does.

04 · assurance

Three rungs, and none of them is identity.

This is the part of the product most likely to be read as more than it is, so here is exactly what each rung means and exactly where it stops.

asserted

Someone typed this address on a page they could already reach. Nothing was sent to it and nothing came back. On an open prototype this is the ordinary state, which is why it is the bottom rung.

vouched

Someone opened a link the person asking handed to that address. It shows the link reached them.

verified

Someone opened a link we emailed to that address. An email round-trip, and nothing more.

Read those three again and notice what none of them says. Each one describes a mailbox and a click. A shared inbox, a forwarded link, a colleague on somebody else's laptop — all of them clear these rungs without anything noticing, because there is nothing here that could notice. We label how well an address was established, and we stop there. None of the three is proof of identity, we do not describe it as one anywhere in the product, and if you find a sentence that does, it is a bug worth reporting.

A floor, not a claim

An ask declares the floor it will accept an answer at: any, vouched, or verified. A floor of asserted is not spellable — "you must have typed something" is not a requirement, it is a description of doing nothing.

A gate floors at verified by default, so the ruling comes from the human's own click rather than from anything acting for them. Pass any to opt out; answering a gate off a link you hand-delivered is a legitimate thing to want, and the engine should not pretend otherwise.

Raising the floor still introduces no account. The only thing an unmet floor ever does is email a fresh link to that address and explain itself: "This ask only takes an answer from someone who opened a link emailed to mike@partner.co. We have just sent a fresh one to that address — open it and answer from there." One tap, and still nothing to sign up for.

A ratchet on the person, a snapshot on the answer

A reviewer only ever moves up. What a response records is the rung it was written on, frozen at that moment. Somebody verifying next month does not strengthen the note they left today, and no later verification quietly upgrades an old record.

When several answers arrive in one burst, the rung we show for the burst is the lowest one in it. A reviewer can comment while vouched and rule after verifying; summarising that as verified would describe the best of what happened rather than the floor of it.

No checksum raises the ceiling

The ceiling is set by the weakest path the person took to get there, and hashing their words does not move it. The checksum described in the next section is tamper-evidence about characters; it says nothing about who typed them. The two travel beside each other and neither implies the other.

Wherever a rung is printed, the sentence explaining it is printed with it. A bare badge with no gloss is how a reader invents the stronger claim we refused to make.

05 · provenance

The copy that counts is the one we cannot reach.

Every response gets a checksum of exactly the words in it. A checksum we compute and store proves nothing to anyone whose doubt is about us — so the anchor is the receipt email sitting in the reviewer's own mailbox, and the checksum is what makes that email checkable.

The checksum

hgr3: followed by 64 hex characters — a SHA-256 over a canonical payload for one response. What goes into it: the response id, the ask, the artifact, the version number, the reviewer as a keyed reference rather than an address, the kind, the body verbatim, any suggested replacement, the ruling, the option they picked, the text they anchored to, the timestamp to whole seconds, the consequence capsule they were shown, and the assurance rung the writing address stood on.

What is deliberately left out, and why:

Text is normalised before hashing, because the same visible "é" has one encoding on macOS and another on Windows. Identical on screen, different bytes, different checksum — and a receipt that fails for a reason nobody can see is worse than no receipt.

The version is inside the value

hgr3: is not decoration. Canonicalisation will change — a field gets added, a normalisation is tightened — and verification always uses the scheme the record itself declares rather than the current one. Old schemes stay implemented forever. Without that, every receipt issued a year ago would silently stop verifying, and there would be no way to tell an old honest record from an altered one.

The receipt email

When a reviewer answers, we email them their own copy: their words, the checksum of those words, and the sentence explaining the rung it was recorded at. That email is signed by our domain, timestamped by their mail provider, and sitting in a mailbox we cannot reach or alter. It is the part of this that is outside our control, which is the only part that does any work in an argument.

It also tells them, in the same email, what the checksum does not do:

What it does NOT do is prove who wrote it. Beside each entry we record how your address was established at the moment you wrote it. That is a mailbox, not a person, and we will never describe it as more than it is.

So the claim is small and it holds: quote them later and the same words produce the same checksum, and different words do not.

Why we call it provenance

We attest to what happened on our wire, and never to what it meant. That is provenance, not a certified audit, and the distinction is not modesty. An agency settling a scope dispute wants "you picked B on 3 July, here is the unaltered record", and that is exactly what this hands over. Claim more and the first person to lean on it in a real argument finds out — and everything else we ever recorded is worth less afterwards.

06 · typed asks

Ask for a value, not a paragraph.

The kind is the shape of the answer; the declaration is the timing. They compose freely — a choice can be courtesy or blocking like anything else.

choice — two to four options

Comes back as {"choice":"b","because":"…"}, in about fifteen seconds. On a gate, the pick is the ruling.

When it beats prose: when you already have the alternatives. Your agent generates them constantly and the expensive part was never writing them, it was deciding between them. A pick is a value your agent branches on. A paragraph is something it has to interpret, and interpreting is where it guesses.

One option is a rhetorical question and both extremes are refused. Two is the smallest set that is a choice at all. Past four the reviewer is doing your agent's narrowing for it, and on a phone the options stop being a set you compare and become a list you scroll.

On a phone they stack full width, each one fully legible, with a sticky bar of jump chips at the bottom where a thumb already is — one tap moves between options at the same scroll position, which is what "side by side" actually buys you. Long bodies are clamped to a comparable height so one option cannot bury the other. On a wide screen they become real columns and the chips disappear, having nothing left to do.

form — one to five questions

Each question is text, scale (1–5), bool, or pick (two to four choices).

When it beats prose: when you were unsure about several specific things and can name them. Your agent writes the form because it is the one that knows what it was unsure about.

Five is the cap, and a sixth question is refused with its reason attached: if you need more than five you are researching rather than asking — narrow it down or send two asks. The cap exists because the agent writes the form, and an agent with an unbounded question budget will spend it. Past five the reviewer is doing research for you, and "about four minutes" stops being a favour anyone does twice.

review — the default

Their words on the thing, about a minute. Use it when you do not know what you do not know. Nothing rewrites, scores or summarises what comes back over the top of it — a machine gloss can sit beside a person's words, labelled, and never in place of them.

Your ask gets checked; their answer never does

Every ask is checked for answerability before it is sent, whatever its kind. A rejection names exactly what is wrong: an objective that asks nothing, one that names nothing, three questions in the slot for one, a leftover {{placeholder}}, options nobody could tell apart, or words that contradict the declaration you chose. Your agent can fix that in a second, and the human on the other end cannot fix it at all. The check scores your ask, it is never shown to the reviewer, and nothing anywhere ever scores a reviewer's answer.

07 · livegate

Dormant until one named person arrives.

Nothing is published, so you cannot install this today. The npm package and the version-pinned CDN build both exist in the overlay repo and neither has been released, so a stock deployment has no script URL and the template tag renders nothing at all. A <script src> pointing at a 404 on your production page is worse than no feature. The rest of this section is what it does, and it is accurate — you can register an origin at /dashboard/sites/ and read the exact snippet with your key filled in, which is enough to put it in front of a security review now.

What works today without it

You can already point an ask at a URL your own app serves. The reviewer gets a plain link, opens the page in their own browser, and answers in their inbox. We never load, embed, fetch or screenshot that page, and nothing is installed anywhere. That is the loop without the overlay. LiveGate is the overlay on top of it — annotating the page itself instead of describing it from memory.

Dormant is the whole design

On an ordinary page view the script reads one string, finds no grant in the URL and no live session in sessionStorage, and returns. No network request, no DOM node, no event listener, no timer. Your visitors, your customers and your own team see the page you shipped.

It wakes only when a person we named arrives holding a grant: single-use, short-lived, minted for one reviewer on one ask about one page. The first thing it does — before it has read its own configuration — is take that token out of the address bar, so it cannot reach your access logs, your analytics, a referrer header or a screenshot. The session that replaces it expires on our clock and cannot renew itself; a new one needs a new link from their inbox.

What it touches on your page, and what it does not

The two facts people get wrong

The CSP entry names this application's own originhttps://humangated.ai — and not an api. subdomain, because there is no such host. Two paths are the only ones on our server that answer a cross-origin request at all, and they answer only for an origin you registered, echoed from your row rather than reflected from the request.

The site key in your page source is public and authorises nothing. It says "this page claims to be that origin", and the server answers "then your Origin header had better be the one on file". The credential is the handoff, minted server-side for one named reviewer.

Known limits

Shadow DOM and cross-origin iframes anchor to the host element rather than refusing with an explanation. Removing the grant from the address bar is untested against a single-page-app router that re-renders on it. A gated ask against a URL is still ruled on in the reviewer's inbox, not in the overlay.

The overlay is MIT, has no runtime dependencies, and is about 8 KB gzipped. Its integrity hash is reproducible from a clone, so you never have to take our listing's word for it.

08 · the trail

Filter on any part of the atom.

One ask is one artifact, one version, one question, one person. That is the unit the record is kept in, so every element of it is something you can filter on — and they AND together.

The artifact · the version number · the reviewer · words in the objective · your own external reference · the ask id · the declaration (courtesy, awaited, required, blocking) · the kind · the status · where the ask came from · the ruling, including none · what you did with it afterwards (applied, declined, superseded) · how it expired · the assurance rung recorded · a date range.

So "every required ask on the refund prompt that Mike let expire" is one query rather than three exports and a spreadsheet. A filter value the page cannot parse narrows nothing instead of erroring, which is why the report is safe to bookmark.

Three shapes, one source

Only actions that mean something to somebody outside the building are exported. The full event vocabulary is a debugging tool, and a record padded with token mints is a record nobody reads to the end.

Reviewer IP addresses are deliberately absent

This was decided once rather than per surface: the address stays in the internal event log and reaches no owner-facing or reviewer-facing surface, ever. An export is an owner-facing surface, exports get forwarded, and a person who never signed up for anything did not agree to that. The export drops those fields by name rather than by convention, so nobody adding a field later has to remember.

There is no geolocation either, at any resolution. City-level at best, wrong through VPNs and carriers, and personal data collected from someone who has no account. If you want a reviewer's local time, they have to tell you.

Every export carries its own limits in its first four lines, so the document arrives wherever it is going with them attached: a record of what happened on our wire, provenance rather than a certified audit, and reviewer IP addresses not included. The assurance column records the rung at the time of writing, never the reviewer's rung today.

Open the trail

09 · what is metered

One number is counted, and you choose it.

The count is asks you open — not emails, not reviewers, not artifacts. It moves only when you decide to ask somebody something.

One ask counts once, whatever happens to it. The reminder at T-24h, the receipt the reviewer gets, the expiry notice and the nudge when an answer is sitting unpulled are all free. Those are ours to send, not yours to trigger, and a quota with invisible line items is the kind people are right to be angry about.

Free is fifty a month. Calendar month, UTC, resetting at midnight on the 1st. Paid plans are not counted.

Nothing already open is ever affected. The count gates opening a new ask and touches nothing else. An ask you have already sent keeps its deadline, still reminds, still expires exactly as it declared, still accepts a ruling and can still be pulled — through a month roll, through a downgrade, through a lapsed card. An agent blocked on a gate cannot be stranded by a billing event, which is the one failure this product could not live with.

When you are over, the answer is an HTTP 402 saying the number, the reset date and what removes the cap. Your agent gets the same sentence, and it is an error rather than a result — a refused ask that read as "asked, waiting" would be a way to walk through a gate.

There is also a daily ceiling on every plan, well above anything a person does, which exists so a looping agent finds out in hours rather than at month end. If you meet it legitimately, say so and it moves.

Two things that are not metered and will not be: how many reviewers you ask, and how many people ever answer. Everything a reviewer touches is free, always.

10 · teams

Set the rule once, not per ask.

An organisation is several people and one record. Kay's agent asks Mike, Dana's agent asks Mike, and both are on the same trail.

Rows still say who wrote them. Nothing moves to a company column — the ask still records the person who opened it, because saying who did what is the trail's entire job. What widens is who may read it.

The plan lives on the organisation. A seat inherits its tier, so two colleagues cannot disagree about what they are paying for. One person is in one organisation, which keeps "whose trail is this ask on" a question with one answer.

Standing sign-off rules. Name a path glob and a reviewer once — src/billing/** to Mike, as required — and every ask any seat opens over those paths is raised to meet it. A rule can only strengthen: an agent that asked for blocking under a required rule keeps its harder gate, because being more careful than the company requires is not a thing to correct.

When a rule changes an ask it says so, in the organisation's own words, including the reason you wrote on it. A rule that silently rewrote an ask would read as a bug the first time somebody met it.

The rules are also published at GET /api/requests/rules, which is how the PreToolUse guard refuses an edit before anybody has decided to ask. That half needs a skills release; the engine-side raise is live now.

Two things that stay per person on purpose: the daily ceiling, because a shared one would let one colleague's runaway loop lock out the other ninety-nine, and Slack, because a webhook points at one person's own channel.

and that is all of it

Nothing on this page is a plan. If something here turns out not to be true of the running product, that is a bug and it is worth telling us about: support@humangated.ai.

The agent-shaped version of the same facts lives at /agent.md. The skills your agent runs are public and MIT, in the skills repo. The service itself is closed source.