🤫husshhussh
🤫husshhusshOnePuppy
The 🤫 magazine
EngineeringConsentBuilding in the open

We Published Forty-Seven Scopes and Built Eight

Our public registry advertised 47 things a person could offer the world. The server honoured 8. The other 39 resolved to nothing, silently, with no error - and five of our own published agent types depended on them. Here is how it happened and what we changed so it cannot again.

hussh Engineering·July 28, 2026·6 min read
We Published Forty-Seven Scopes and Built Eight

At hushh.ai/pchp/scopes.json there is a file that calls itself the canonical scope registry for the Preference Subscription Fabric. It is public. Agents fetch it to learn what a person can offer the world. It listed 47 scopes — privacy preferences, sizes and channels, what someone is in the market for, favourite brands and artists.

The server implemented eight of them.

The other thirty-nine resolved to zero fields. Not with an error — silently. A subscriber could hold a valid, signed, receipted grant for favorites.brands, call the read endpoint, get a clean 200, and receive nothing. Forever. Nobody would be told.

How something like this happens

Not through carelessness, which is the uncomfortable part.

The catalogue lived in the frontend, published as JSON. The field bindings lived in the backend, as a Python dictionary. Both were reasonable. Both were maintained. Neither knew the other existed, and no test compared them — so they were free to drift, and drift is not an event. It is what happens when nothing stops it.

The drift was also invisible by design. The resolver is fail-closed: a scope it does not recognise contributes no fields. That is the correct behaviour and we would not change it. But fail-closed and silent are different things, and we had built the first without noticing we had also built the second.

We found a third copy of the same vocabulary while fixing it. The directory's connect-the-dots flow grants wants.* scopes directly, and eight of the eighteen it offered — chiropractor, physical therapist, eye care, massage, acupuncturist, pediatrician, dermatologist, podiatrist — had never been published in the registry at all. Three sources of truth for one vocabulary, two of them wrong.

What it actually cost

Five of the fourteen agent archetypes we publish — advertising, targeting, shopping, personalization, publishing — request favorites.brands or favorites.things.

All five were decorative. They named scopes the server could not bind. Every one of them would have returned an empty payload to anyone who built against it.

And there was a second gap underneath. The API that writes a person's profile accepted exactly one section and dropped every other. So privacy.* — the input to the Google Consent Mode payload, the entire brand-facing product — had no write path at all. The pipeline was reading data that nothing could produce.

The fix, and why it is shaped this way

The hand-maintained map is gone. A scope now binds to the profile path of the same name — which was already true for every privacy scope and for the whole taxonomy. Only two legacy bindings needed stating explicitly.

That change alone takes the count from 8 to 58 and makes adding a scope a JSON edit rather than a code change and a deploy.

The server now vendors the published catalogue byte for byte, and pins its SHA-256. If the two copies ever differ, the build fails. We considered having the server fetch the file over the network instead and rejected it: the resolver sits on the fail-closed read path, and a network dependency there fails either open, which is unacceptable, or into an outage on a CDN blip.

Changing the registry now requires updating a digest in two repositories in the same change. That friction is deliberate. It is a published standard, and standards should be slightly annoying to alter.

Then the guards. Every published scope must resolve to at least one field — the direct inverse of the bug. Every want the directory offers must exist in the registry. Health and legal intent must stay marked sensitive. The free-handshake bundle must resolve and must stay coarse.

We tripped the guards ourselves within the hour

Two of them, immediately.

The sensitivity guard failed because I had written it as a rule about a whole family of scopes, and the registry deliberately treats childcare and elder-care differently from tutoring and pet care. I had encoded my own opinion as a test. That is a real distinction about vulnerable dependents and it was not mine to overwrite silently, so I narrowed the guard and left the question for a human.

Then the coarseness guard failed on a label that reads *"never a street or ZIP"* — my regex was forbidding the word "zip" anywhere, and the label mentioning ZIP in order to rule it out looked identical to a violation. Labels should be free to name the thing they are disclaiming. It is the scope names that must not offer that precision.

And the largest one: while writing about the free first handshake, we specified three fields — profile.age-band, profile.sex, profile.region — and shipped the economics before publishing the scopes. For a few hours the handshake promised to disclose fields that did not exist in the registry. The exact drift we had just spent a day eliminating, reintroduced by the person eliminating it.

The guards caught all three. That is the argument for guards.

Why write this down

Because the finding generalises, and because the alternative is worse.

A published contract with no test against the implementation is a wish. If you publish an API surface, a schema, a scope registry, a feature matrix — anything that says *here is what we do* — and nothing in your build compares it to what you actually do, the two will separate. Not immediately. Gradually, then completely.

Fail-closed is necessary and not sufficient. Failing safely is not the same as failing loudly. Ours failed safely and told nobody for an unknown length of time.

And we would rather you heard this from us. We publish a page listing what we have not done, we say our certifications are in pursuit rather than held, and this belongs in the same category. A company whose entire product is trust does not get to be selective about which unflattering facts it shares.

Where this actually stands, today

It would be a poor article about overclaiming that overclaimed in its last line, so precisely:

Shipped and live. The registry publishes 58 scopes, including the eight health wants the directory had been offering unpublished. The write path accepts every published root — before this, a privacy preference had nowhere to be stored. The guards that compare the three copies of the vocabulary run in our build.

Written, tested, not yet deployed. The resolver change — the one that takes the server from 8 to 58 — is verified against a real Postgres database and is open for review in the protocol repository. It is not in production as this is published. Until it deploys, the honest count is 58 published and 8 serving.

We are publishing this now rather than after the deploy, because "we will tell you once it looks good" is how the first gap lasted as long as it did. This page will be updated with the date the resolver ships.

The counts are public either way, and there is now a test that fails the day the published number and the built number disagree.

The 🤫 hussh magazine

Written by hussh Engineering, and built to read beautifully here — and to travel to 🤫 One on your phone, your glasses, and visionOS, as one immersive magazine you own.

More from the magazine →Back to top ↑

Keep reading

More stories from the magazine

July 28, 2026

We Tried to Break Our Own Ledger

We attacked our own consent ledger and found three real flaws - a chain that could be silently truncated, a race between reading and revoking, and an error message that leaked. Here is what broke, how we fixed it, and what we still cannot promise.

July 28, 2026

What Shipped: The Permission Gateway, July 2026

An honest product update on the Permission Gateway - what is running, what three security findings we fixed, what is still blocked, and what we deliberately have not built yet.

July 28, 2026

🤫 The World Subscribes to You

For thirty years the internet subscribed to you without asking. We built the opposite - one profile you own, and a world that subscribes only to what you grant, with a receipt for every access.

Products

  • Agent One
  • The 🤫 One app
  • Puppy One
  • Which Puppy is right for you?
  • The Puppy 100
  • Tag One
  • The 🤫 Store
  • The 🤫 One Card
  • Pricing
  • Claim your One
  • The product roadmap

🤫 Yellow Pages

  • The 🤫 Yellow Pages
  • Discover in the feed
  • Find a local expert
  • Coverage & markets
  • Connect - in Agent One
  • Ping an expert

Business & Enterprise

  • 🤫 for Business
  • Small & medium business
  • 🤫 Concierge (VVIP)
  • 🤫 for the Enterprise
  • Industry solutions
  • Federal government & agencies
  • 🇺🇸 Defense & national security
  • For advisors (RIAs)
  • Partner Portal
  • One for Sellers
  • Developers

Watch, read & learn

  • The media library
  • The 🤫 Feed
  • See it in a minute
  • Listen - the podcasts
  • Blogs
  • The field guide - the book
  • Research & papers
  • Guides - by topic
  • Academy
  • The Heartbeat
  • Wiki

Company & open

  • About
  • Team
  • Investors
  • Fund A
  • Building in the open
  • News & investor relations
  • Release notes
  • Careers
  • Contact
  • Explore - the whole site, mapped
  • Sitemap

Trust, rights & gratitude

  • The Hussh Protocol (PCHP)
  • Day 0 Trusted Circle
  • The case - a right, made enforceable
  • Data-rights landscape
  • Accessibility
  • 🤫 Champions of the Community
  • 🤫 Faculty - the professors
  • Gratitude - people we admire
  • The 1024 - humans of the world
  • Search every page
  • Browse (developer view)
🤫husshhusshKirkland, WAPrivacyTerms

© 2026 Hushh Technologies Corporation - an independent company.