# 8,584 organisations discovered, 680 with verified addresses, 11 drafts, 5 emails sent: the outreach pipeline and every gate in it

slug: outreach-machinery · https://miscsubjects.com/a/outreach-machinery · category: canon · tags: system, protocol, governance, agents, marketing, canonical, ongoing · updated 2026-08-03T04:00:01.841Z

## What this page documents

This build has a working lead-discovery and outreach system. Until this page existed, none of it was documented anywhere a reader outside the build could see: the scrapers, the enrichment crawler, the qualification gates, the drafting validator, the send gate, the tracking, and the channels it can speak on were internal tooling described only in code and in an administrative view nobody else can open.

The same is true of everything adjacent to it: the image and video generation, the fifty-eight paid-advertising rows, and the machine-readable documents that are the only promotion surface written for a program rather than a person.

This page documents all of it to the same standard as every other capability here — the real row names, the real code paths, the real tables and columns, the real gates, the real costs, and the real counts as they stand at publication. It documents what the system does **not** do, and then what it does not **have** — every channel and interface a system like this should hold and does not — because for a promotion system that complement is the more load-bearing half.

Two things follow it. The first is the logic that decides who should hear about this build at all, derived from the published corpus rather than asserted. The second is the arithmetic that decides how many of them are contacted on a given day, through which channel, with which artifact — recorded, replayable, and openable by the person it selected.

## Why it is being published

The most common objection to this build, raised by nearly every model that has been shown it, is not architectural. It is that nobody else has adopted it. The architecture is granted and then dismissed on that ground.

That objection is correct on its facts and the number is in this page. It also has a structure worth naming: the thing being asked for is external demand, and the honest way to produce external demand is to reach the people whose problem the build addresses and let them check it. Doing that with an undocumented, unreviewable outreach system would reproduce, one level up, exactly the failure this build exists to refuse — an action taken for reasons nobody outside the actor can inspect.

So the outreach machinery is documented first, on the same terms as everything else: the mechanism is public, the decision is receipted, and the reason a particular recipient was selected is a record that recipient can open.

## One door

Every capability named below is a directory row invoked the same way:

```bash
curl -s -X POST https://miscsubjects.com/api/dispatch \
  -H 'content-type: application/json' \
  -d '{"key":"LEADS_VERIFY_MX","body":"25"}'
```

The invocation is appended to the ledger — key, actor, inputs, result, cost, trace — before the result returns to the caller. Each one is then readable at `/receipt/<invocation id>`. That property is what makes the rest of this page checkable instead of merely descriptive.

[[embed:source:s9]]

## Discovery: four independent sources, one table

Discovery finds candidate organisations. Four rows do it, from four sources that fail in different ways, and all four write into one table with a uniqueness constraint on name and city so the same organisation cannot be counted twice.

| row | source | cost | what it yields | how it fails |
|---|---|---|---|---|
| `LEADS_DISCOVER` | OpenStreetMap via Overpass | free | name, website, phone, address, tag context | coverage is volunteer-dependent and thin for professional practices |
| `LEADS_DISCOVER_PLACES` | Places text search | metered per request, written into the result | name, website, phone, formatted address, rating, type | costs money per call and returns commercial listings only |
| `LEADS_DISCOVER_NPI` | NPPES federal registry | free | authoritative identity, phone, address, taxonomy | contains no website at all |
| `LEADS_DISCOVER_AI` | live web search | model tokens | organisations the other three miss | least structured and least verifiable of the four |

Every one of them discards a result that has neither a website nor a phone number. A record with no reachable contact cannot pass any later stage, so it is refused at entry rather than stored and counted.

[[embed:source:s1]]

[[embed:source:s3]]

The insert is a conflict-ignoring insert that returns the new identifier only when a row was actually created, so a discovery run reports how many records are new rather than how many results it saw. Both numbers are in the result.

## Resolve: giving the authoritative rows something to crawl

The most reliable identity source has no website field. A separate row looks up siteless records by name and city and attaches the website, which is the only thing that makes the next stage possible. This is the stage that decides whether personalisation can happen at all — not the writer, and not the model.

## Enrichment: the target's own site, and nothing else

Enrichment fetches the organisation's own website and reads a fixed list of paths on it — the homepage, then the conventional contact, about, team, services, and location paths. Addresses are extracted four ways: visible text, mail links, structured data, and de-obfuscation of protected addresses that are rendered as encoded attributes rather than text. A junk filter removes placeholders, platform addresses, and content-delivery artefacts. An address on the organisation's own domain is preferred; a role address is next.

The same pass captures the site's own title and description, and stores them as the record's context.

Two properties matter more than the extraction detail.

**The only permitted source of contact data is the target's own website.** No purchased list, no third-party contact database, and no pattern-guessed address can enter the system through this path. If the organisation has not published an address, the record ends as *no address found* and is never drafted.

**The stored context is the only material a draft may personalise from,** and it is displayed beside every draft along with the URL it came from. A personalised sentence with no recorded source is indistinguishable from an invented one, so the source is a column.

A batch version processes several records at a time and stamps a claim timestamp on each, with stale-claim recovery, so two workers running concurrently never enrich the same record twice.

## Verification: what a verified address actually means

Mailbox verification looks up the mail-exchange records for each address's domain over HTTPS, because a Worker has no DNS socket. Domains with no mail server are parked so that no draft and no send is ever spent on them.

[[embed:source:s4]]

The limit has to be stated in the same breath as the check: this proves the **domain** accepts mail. It does not prove the individual mailbox exists. A role address on a live domain can still bounce, and any claim stronger than that is false.

## Qualification: a score, and the study that does not exist

A model reads each verified record against a stored thesis document — what is being offered, to whom, and why they would want it — and returns a score out of one hundred, a counterparty type, and a one-line concrete reason. The score and the reason are written back onto the record, so the list can be ordered by judged fit rather than by whether a website happened to be found.

Records below the floor are never drafted.

**No calibration study exists for that score.** It is a model's estimate of commercial fit, it gates every later stage, and its error rate is unmeasured. That is the largest unquantified term in the whole pipeline and it is not improved by describing it in stronger language.

## Drafting: preconditions, then a validator that destroys its own output

The drafting row refuses to run at all unless every one of these holds: an address was found on the organisation's own site, its domain accepts mail, the qualification score is at or above the floor, there is a minimum quantity of real site context to write from, and the recipient is not suppressed. A missing input produces a refusal, not a plausible sentence written around the gap.

When it does run, the finished draft is then checked and — if it fails — **discarded and retried before anything is stored**. The checks include banned phrases, a subject-line contract, register violations, and claims outside the permitted class. A validator that runs after saving produces a corpus that has to be cleaned later; one that runs before saving produces a corpus that never contained the defect.

## Template collapse, and how it is measured

The most expensive failure this system has produced was not a rule being broken. It was a rule being obeyed.

A personalisation rule was tightened until it banned every observation the target sites actually contained. One legal opener remained, and one hundred and twenty-one drafts converged on it under the same four-word subject. Every draft passed every validator. Interchangeable mail is unwanted mail regardless of how strict the rules that produced it were.

The detector for it is structural. A draft's *shape* is what remains after the personalised opener, the catalog block, every URL and every number are removed; that residue is hashed. Two drafts written under the same rules produce the same hash. Clustering the corpus on it turns a pile of near-identical bodies into the handful of generations the copy has actually been through, and the count of distinct businesses inside one shape is the collapse measurement.

Every change to the drafting rules is stored verbatim with its timestamp, and the shape clustering is re-run after the change. The rule history and the corpus it produced are inspected together, because a rule change is only evaluable against the output it caused.

## Review: nothing reaches a recipient unreviewed

Drafts are mailed for review with the recipient, the subject, and the full body, one per draft. Nothing is sent to any recipient until that review has happened.

Review mail deliberately carries **no** link wrapping, unlike outbound mail. Wrapping rewrites the visible destination of every link, and a review message carrying a dozen rewritten links is a text-and-destination mismatch on every one of them — which is what filters score as impersonation. That was not theoretical: a wrapped review batch went to spam while earlier unwrapped mail arrived.

## The send gate

The send row refuses unless the caller passes a literal confirmation token as the first argument. It is not a parameter with a default; the absence of the exact token returns a refusal that sends nothing.

With the token, it re-checks all of the following **at send time**:

1. the record is in the drafted state;
2. its domain still passes the mail check;
3. its qualification score is still at or above the floor;
4. the recipient is not in the suppression table;
5. this address has never been sent to before, by any record;
6. a valid physical postal address is configured;
7. the sending domain's authentication alignment is flagged as proven.

Then it appends the disclosure footer — the postal address, and a one-word reply that stops all further contact.

[[embed:source:s5]]

Re-checking is the whole point. Every one of those conditions was already checked when the draft was written, and any of them can have changed since. An approval that is not re-verified at the moment of action is a memory of an approval.

The batch version caps the number it will send and runs the entire gate again per record, so a batch is a loop over individual gated sends and not a bulk path around them.

[[embed:source:s6]]

## Tracking, and its unreliability

Outbound mail has its links rewritten through a redirect that counts clicks, and carries a single-pixel image that counts opens. Delivery status, open count, first and last open, click count and a click log are stored per send.

Open tracking is unreliable and should be read as a floor, not a measurement: image blocking, privacy proxies, and prefetching all break it in both directions. Click tracking is more reliable and still not proof of a human.

## Follow-ups

A follow-up row drafts a short threaded sequence off the first message. It is subject to the same review-before-send rule, and to the same never-twice constraint at the address level.

## The channels, and the completion contract on each

| channel | rows | state | what counts as done |
|---|---|---|---|
| email | `EMAIL_SEND`, `EMAIL_SEND_TRACKED`, `LEADS_SEND`, `LEADS_SEND_BATCH` | live | provider accepted the message, and a tracking row exists |
| X | `X_POST`, `X_REPLY`, `X_SEARCH` | live, owner account, user-context OAuth | provider success status, non-empty id, and the status URL built from that id |
| Reddit | `REDDIT_SEARCH`, `REDDIT_THREAD`, `REDDIT_REPLY` | reads and replies implemented; the reply lane needs two more credentials than the read lane | the provider's comment identifier and its permalink |
| iMessage | messaging-provider rows, with a capability probe per number | live | provider delivery event for the specific message |
| WhatsApp | messaging-provider rows | live | provider delivery event |
| Telegram | dedicated route | live | provider message identifier |
| paid delivery | fifty-eight advertising rows, read and create | live, never used for this build | the platform's own object identifier for the created campaign, ad set, ad or creative |
| creative production | image, video and ad-format generation across four providers | live | the stored asset and the request that produced it |
| machine-readable | `/llms.txt`, `/sitemap.xml`, `/feed.xml`, two well-known descriptors | live | a fetch of the document, logged |

[[embed:source:s8]]

[[embed:source:s7]]

The X completion contract deserves its own line because it was written against a real repeated failure: a model reported a post as published while holding only its own receipt for having attempted it. A receipt proves a call was made. Only the provider's identifier and the resulting status URL prove a post exists. The same standard now applies to every channel in the table: the provider's own identifier, or the action is not done.

## Machine-readable discovery: the channel with no recipient

The cheapest promotion this build does has no message and no send. It is a set of documents written for a program rather than a person.

| surface | what it is for |
|---|---|
| `/llms.txt` | a plain-text index of the site, written so a model reading it can find the substantive pages without parsing navigation |
| `/sitemap.xml` | every page, for crawlers |
| `/feed.xml` | changes, for anything that subscribes |
| `/.well-known/agent.json` | a descriptor telling an agent what this site is and how to call it |
| `/.well-known/oip.json` | the object protocol descriptor: the shape of every addressable object here |
| `/api/dispatch`, `/api/relay`, `/receipt/<id>` | the enumerable capability surface and its history |

[[embed:source:s14]]

This matters more for this build than it would for most. A meaningful share of the audience for an auditable-reasoning primitive is not a human browsing — it is a coding agent or a web-based model asked to evaluate something, which will read whatever is machine-addressable and ignore whatever is not. Making the capability surface enumerable, and every claim traceable to a receipt an agent can fetch, *is* the promotion. A page a model cannot verify is a page a model will hedge about.

## Making the creative: images and video

Creative production is inside the same receipted system as the send.

| capability | rows |
|---|---|
| ad-format image and video generation, uploaded to object storage | creative-platform rows including a credit check, a generate call, a video generate call, and an upload-to-storage step |
| general image generation | two independent model providers, each with a direct call and a store-to-object-storage variant |
| image editing | provider edit rows |
| short video generation | a start-and-poll pair |
| text-to-image on the platform's own inference | one row |

Four independent providers exist for images, so a provider refusal or outage is not a stop. The generating request is preserved alongside the asset, which is what allows an image, the message that carried it, and whatever came back to be joined afterwards rather than guessed at.

Every featured image on this site, including the one on this page, was produced this way.

## Paid channels: the ads surface

The build holds fifty-eight rows against a paid advertising API. Not a read-only integration — the create paths exist:

- **read**: accounts, businesses, portfolio, campaigns, ad sets, ads, creatives, images, videos, audiences, pixels, catalogs and their diagnostics, activities, studies;
- **create**: campaign, ad set, ad, creative, custom audience, lookalike audience, catalog;
- **change**: budget set, status set, campaign update, ad set update, ad update, object delete;
- **measure**: insights, asynchronous insights create/status/result, dataset stats, delivery estimate;
- **target**: targeting search and targeting browse;
- **report back**: one server-side conversion row.

[[embed:source:s11]]

[[embed:source:s12]]

**Zero has been spent promoting this build.** The advertising account those rows are bound to belongs to a different venture. The capability is real and the use is nil, and the distinction between those two things is exactly what this page exists to make legible.

The reason the paid lane is documented next to the free one is that they are one loop, not two. A paid impression and a cold email are both a spend of something scarce against a hypothesis about who cares; both produce a signal; both signals move the same terms in the same equation. The only structural difference is that the paid lane can be bought in volume before the hypothesis is any good, which is the argument for its coming last rather than first.

## What it does not have, and should

An inventory of a promotion system that lists only what it can do reads as complete. This is the complement — every channel and interface that is absent, with what its absence costs.

| absent | what it would do | cost of not having it |
|---|---|---|
| TikTok Content Posting and Marketing APIs | organic posting and paid delivery on the platform with the largest current attention surplus | the entire short-video audience is unreachable |
| Google Ads API | intent-side paid delivery — reaching a search rather than an interest | no way to appear at the moment someone searches for the problem this solves |
| LinkedIn Pages and Marketing APIs | the professional network where the audience classes for this build actually work | the single largest miss for a business-to-business primitive |
| YouTube Data API | publishing demonstration video where technical evaluation actually happens | a demonstration has nowhere durable to live |
| Instagram Graph publishing | scheduled organic publishing | ad rows exist for the platform; organic publishing does not |
| Threads, Bluesky and Mastodon | the developer-adjacent networks displacing a share of X | one microblog is a single point of failure |
| Discord and Slack | the closed communities where technical adoption is actually argued | no presence where practitioners talk |
| Product Hunt, Hacker News, developer-community submission | one-shot launch surfaces with real reach for infrastructure | no launch mechanism at all |
| compliant application-to-person SMS | text as an outbound channel under a registered campaign | messaging exists only as a reply channel, correctly, because the compliant path is unbuilt |
| a mail provider with deliverability reporting | bounce, complaint and reputation data as first-class events | delivery is inferred from an accepted request, and complaints are invisible |
| IndexNow and search-console interfaces | announcing each change and reading back what indexes and what ranks | the site publishes and waits, blind to its own search performance |
| a newsletter surface | a subscription that does not require the build to initiate | every contact must be outbound; nobody can opt in |
| review and comparison directories | third-party listings buyers consult before contacting anyone | absent from the places evaluation actually starts |

[[embed:source:s13]]

That table is not a wish list. It is the input to the same allocation described below: an absent channel with a high-scoring class behind it is a build task with a priority, and the reason it is published is that the gap list is the part of a self-promotion system nobody writes down.

## What it does not do

- **No LinkedIn.** There is no LinkedIn capability of any kind — no posting, no messaging, no scraping. A reader assuming otherwise from a list of channels would be wrong.
- **No cold direct messages, on any channel.** iMessage, WhatsApp and Telegram are reply channels and warm channels. A cold message to a personal phone number is not a lower-friction email; it is a worse one, and no row exists to send it.
- **No purchased or third-party contact lists.** Contact data enters only from the target's own published website.
- **No guessed addresses.** No first-name-dot-last-name construction against a domain, ever.
- **No scraping behind a login, and no automated defeat of bot checks.** The crawler fetches public pages of public sites.
- **No sending without a human review of the exact body**, and no sending twice to one address.
- **No claim of delivery, open, or adoption that is not backed by a provider record.**

## Who would care, and how that is decided

The audience logic is derived, not asserted. Independent models — from different training families, the same channels the adjudication panel uses — read the published corpus and answer one question each: *who bears a loss this machinery reduces, and what is the one sentence that would make them reply?* Their full requests and responses are stored as ledger objects, so the reasoning that produced a class is readable and can be attacked directly.

A class is stored as a record with: the loss borne, the mechanism that addresses it, the single strongest artifact to show that class, a one-sentence thesis, the counter-argument that class will raise first, and a fit score with its reason. The drafting row reads the class record the same way it reads any other thesis document, so the same code writes to a regulator and to an infrastructure engineer without a fork.

The starting classes are candidates, scored and cut on evidence, not a finished list: assurance and audit technology, litigation support and discovery engineering, model-risk and AI-governance functions inside regulated firms, conformity-assessment and standards bodies, underwriters of professional and technology liability, agent-infrastructure and protocol builders, evaluation and interpretability researchers, procurement functions that must evidence diligence, public-sector oversight bodies, and the platform teams whose primitives this is built on.

The scoring question for each is deliberately narrow: does a wrong decision in their work cost money or licence, do they already pay for attestation of some kind, can one person there act without a committee, and does a page on this site already speak to their specific loss.

## The delta equation

Volume is not a target. It is the output of an equation whose terms are recorded.

For a class `c`, a channel `k`, on a day `d`:

```
priority(c,k,d) = fit(c) · novelty(c,d) · permission(c,k) · (1 − saturation(c,k,d)) · prior(c,k)

volume(c,k,d)   = clamp( round( cap(k,d) · priority(c,k,d) / Σ priority ), 0, cap_class(c,d) )
```

- **fit** — the class score, from the derivation above.
- **novelty** — what has shipped since this class was last contacted that is *relevant to this class*: a new article, a new claim, a new receipt, a new capability, a resolved defect. **Zero new relevant material is zero novelty and therefore zero volume.** This is the term that makes the system incapable of running a drip sequence: with nothing new to show a class, it does not write to that class.
- **permission** — one for a published organisational address on a channel that class has permitted, zero otherwise. It is a gate that can only zero the term, never a weight that trades against the others.
- **saturation** — how much of the class has already been contacted on this channel in the trailing window, plus a hard per-domain rate.
- **prior** — a declared constant to begin with, updated only by recorded events: replies, opt-outs, complaints, and the reviewer's verdict on each draft.
- **cap** — the daily channel ceiling, set low enough that every message remains individually reviewable.

Each run writes one ledger object holding the policy version, every input term for every class, the resulting volumes, and the identifiers of the records selected. The allocation is therefore replayable and contradictable — someone can recompute it, disagree with a term, and point at the exact number they disagree with.

[[embed:source:s10]]

**The prior is the weakest input.** With no response data, the first wave's ordering rests on an estimate. It is published as an estimate, and the first real replies will move it.

### The receipt the recipient can open

Every message carries a link to the arithmetic that selected its recipient: the class, each input term, the artifact chosen, and why. The link resolves for that recipient, through a token issued to them, using the same audience-bound mechanism this build already uses for blinded human review.

Class-level allocations are public. A named recipient's record is not, and publishing one to demonstrate transparency would be precisely the harm the transparency is for.

## What happens when someone replies

- **A one-word stop** writes the address to the suppression table, which every gate consults before every draft and every send. Nothing further is possible to that address.
- **A substantive reply** is a first-class event, stored, and it updates the prior for that class rather than being read as a private success.
- **"This is spam"** is treated as a defect report about the machinery, not about the recipient. It is recorded against the class and the shape that produced it.
- **"You are wrong"** is the reply the machinery is most interested in, and it has a place to go: the objection log, attributed and dated, alongside every other objection raised against this build.

## One loop over every channel, free and paid

The loop is five steps and each hop is a receipt.

1. **Something ships** — an article, a capability, a resolved defect, a measurement, a generated asset.
2. **The novelty term changes** for whichever classes that thing is relevant to. Nothing relevant, no contact.
3. **The allocation recomputes** — who is worth reaching today, on which channel, with which artifact. The artifact changes when a newer and stronger one exists. The channel set includes the free lanes, the machine-readable surfaces, and the paid lane, priced in the same units.
4. **Signal comes back** on every lane and into the same table: replies, opt-outs, complaints and reviewer verdicts from the direct lanes; impressions, clicks and cost from the paid lane; traffic, referrers and which pages were actually read from the analytics surface; and — the signal specific to this build — which receipts and which machine-readable documents were fetched, and by what.
5. **That signal moves two things, not one.** It moves the priors and class scores, which changes the next allocation. And it moves the **gap list**: a class that responds through a channel the build does not have turns the absence of that channel into a ranked build task. What the build learns about who finds it interesting steers what it builds next, not only who it writes to next.

Step five is the part that makes this different from a marketing pipeline. The output of the loop is not only a message; it is a change to the build's own priorities, produced by evidence about which of its capabilities anyone actually cared about.

There is nothing autonomous about the send. A human reviews every body before a first contact to any class. What is automated is the *reasoning about who and when*, and that reasoning is recorded in a form that can be read back and contradicted. That is the same standard this build applies to every other decision it makes; outreach is not an exception to it.

## The honest state, in numbers

At publication:

- **8,584** records discovered and not yet enriched.
- **680** enriched with a verified address; **814** where no address was found on the target's own site; **18** parked for having no mail server; **7** where no website could be resolved at all.
- **11** drafted and awaiting review; **8** rejected.
- **41** review messages sent to the reviewer, and **1** deliverability test.
- **0** addresses in the suppression table, because no recipient has yet asked to be removed.
- **0** spent on paid delivery for this build, across fifty-eight available advertising rows.
- **0** posts, replies or messages sent about this build on any social or messaging channel.
- **11** emails sent to external recipients — all of them on 2026-07-06, all for a different subject, and all before the confirmation gate existed. That gate exists because of them.

**No party has been contacted about this build.** The machinery above has been exercised end to end for another subject. Its audience logic for this subject has never been run against a real recipient, and the first wave has not been sent.

## Defects, stated before anyone has to find them

1. **The eleven sends are not in the tracking table.** The single-send path updates the record's status and does not write a tracking row, so the send table shows zero outbound messages while eleven records say sent. Two sources of truth that disagree, in the direction that understates activity.
2. **The qualification score has no calibration study.** It gates everything and its error rate is unknown.
3. **The response prior is a declared constant.** Ordering the first wave with it is an estimate presented as an estimate.
4. **Open tracking is unreliable** in both directions, and no engagement number from it should be read as a measurement.
5. **A verified address is a verified domain.** Individual mailboxes are unproven until a message is accepted.
6. **The audience classes are model output about the build's own value,** produced by models that were shown the build's own corpus. A promotion system grading its own targeting is a conflict it cannot resolve from the inside. That is the specific reason the outbound message asks for external audit rather than asserting significance.
7. **The paid lane has no attribution wired to this subject.** The conversion row exists and no conversion definition for this build does, so a paid impression could be bought today and its outcome could not be joined to anything.
8. **The analytics signal is not yet an input to the allocation.** Traffic and referrer data are collected and readable; the equation does not read them. Until it does, step four of the loop is smaller than described here for the free lanes and empty for the paid one.
9. **Nobody outside has adopted this.** It remains the strongest objection, and the number above is the answer rather than an argument.

## Wave one, as it stands

The loop above stopped being a description on 2026-07-30. In order, each step receipted:

- **Audience derivation ran** across model families: [inv_6ak9uz7fic](https://miscsubjects.com/receipt/inv_6ak9uz7fic) (kimi-k2.7-code, eight classes with losses and objections) and [inv_bbwnx5ce85](https://miscsubjects.com/receipt/inv_bbwnx5ce85) (gemini-2.5-flash, seven). One channel answered a different question than the one asked ([inv_gi55ouniaz](https://miscsubjects.com/receipt/inv_gi55ouniaz)) and one refused on a spending limit ([inv_6b9a8ovtmm](https://miscsubjects.com/receipt/inv_6b9a8ovtmm)) — both recorded rather than retried into silence. Eight classes now sit in the class table, fit 55–85, priors declared at 0.05.
- **The allocation ran live**, twice: [inv_6gaq45opcm](https://miscsubjects.com/receipt/inv_6gaq45opcm) before any organization existed to select, and [inv_sta3m7a809](https://miscsubjects.com/receipt/inv_sta3m7a809) after discovery — eight classes at full novelty, volume one each, five with a selected record. Both runs report `sends_performed: 0`.
- **Forty real organizations** entered through discovery with each website verified alive at insert; thirteen published an address on their own site and all thirteen domains verified; twenty-seven published none and will never be drafted.
- **The owner reviewed the full packet** — every party, every selection reason, every draft body — and approved sending.
- **Three model families reviewed the drafts before any send**: [inv_j9hcpxketv](https://miscsubjects.com/receipt/inv_j9hcpxketv) (glm-5.2), [inv_pu9flpr6d3](https://miscsubjects.com/receipt/inv_pu9flpr6d3) (kimi-k2.7-code), [inv_8rxiu0po4g](https://miscsubjects.com/receipt/inv_8rxiu0po4g) (gemini-2.5-flash). Their convergent finding: two drafts clean, three openers described the recipient's industry rather than the recipient. The three openers were rewritten to the reviewers' specification and the revised drafts staged on their records — the peer review is part of the pipeline now, not a courtesy.
- **The five first contacts are sent.** Each went through the full gate — CONFIRM token, drafted state, mail-domain check, score floor, suppression check, never-sent-before check — and each send is a receipt: [inv_uvpxjk93te](https://miscsubjects.com/receipt/inv_uvpxjk93te) (an AI-certification body), [inv_tqncce1bis](https://miscsubjects.com/receipt/inv_tqncce1bis) (a model-risk practice), [inv_k8jba7c0cp](https://miscsubjects.com/receipt/inv_k8jba7c0cp) (an audit-AI vendor), [inv_otiekxkpxp](https://miscsubjects.com/receipt/inv_otiekxkpxp) (an ediscovery platform), [inv_hi8zwbvp3t](https://miscsubjects.com/receipt/inv_hi8zwbvp3t) (a model-infrastructure company). The provider accepted all five with a message id each.
- **The owner ruled on identity before the first send, and the ruling is now a mechanical gate.** These messages are feedback requests, not commercial solicitation. They carry no person's name, no postal address, no business name, and no compliance-footer phrasing — the message is the body and the model signature, nothing else, sent as miscsubjects.com. An identity guard in the send path now refuses any feedback-mode send matching a person, business, address, or footer phrase, and a copy of every outbound message lands in the owner's inbox. The five classes contacted are stamped, so their novelty term is zero until something new ships — the loop cannot write to them again with nothing new to say.

## After a send: the standing logic

What happens next is not decided next — it is decided now, and it is the same five rules every time:

1. **A reply** is recorded, moves the class prior, and is answered by a person, not by the loop.
2. **A one-word no** writes the address to the suppression table permanently.
3. **No reply** earns at most a follow-up, and only when the novelty term is positive — something real must have shipped since the first message. Three touches is the ceiling, ever, per address.
4. **A complaint** is a defect filed against the class and the copy shape that produced it, not against the recipient.
5. **Every one of these events** updates the same allocation inputs the next wave is computed from, on the ledger, before the next wave runs.

## Whether this is the template

The question this wave was run to answer, recorded here as asked: is this the end-to-end shape of a firm run this way — a system that builds its own capabilities, documents them, derives who should care, reaches them, and steers its own building from what comes back, with every step inspectable?

**In shape, yes.** One system produced the capability, the public documentation of the capability, the audience logic, the allocation, the creative, the review packet, and the record of all of it — through one door, on one ledger, in one working day. Nothing in the loop is specific to promotion: the same shape (ship → derive who bears the loss → show them → record what returns → let it steer the next build) is how any function of a firm would run on this substrate, and the paid rows, creative rows, and commerce rows already exist for the functions that come after this one.

**In fact, not yet, on three counts.** No revenue has closed through this loop. It has one operator and one node, and the objection log holds that objection already. And the human review gate is load-bearing by design — the loop decides whether, whom, when and with what; a person still decides *go*. Removing that gate is not a roadmap item; it is what this build exists to refuse.

## What is being asked for

Three questions, and they are the reason a message gets sent at all:

1. **Where is this most commercially valuable, and to whom** — from someone who actually buys in that market.
2. **What is the strongest objection to it** that the objection log does not already contain.
3. **Which of the build's claims about itself do not survive contact with your practice.**

Every one of those has a place to be recorded, publicly and attributed, whether the answer flatters the build or ends it.


## The literal procedures — zero ambiguity

This page is an official ongoing record. The procedures below are the exact, binding recipes; the governing object is [The Loop Law](/a/loop-law) and a wrong behavior is fixed by amending it there, never by re-explaining it to a model.

**How a subject is chosen.** `GET /api/articles/next-acts` — the ranked queue derived live from the corpus graph. Take the top act. The ranking, in order: missing pages (wikilinked from published bodies but never written), claims under active challenge, unsourced claims, stale hubs, orphans to connect, unread replies, quiet high-fit audience classes. A model does not invent a subject while the queue is non-empty; the owner's named target overrides the queue.

**How an article is written.** Definitive depth (11-15k characters, ~10 claims with tiers and source_ids, 6-8 openable sources, a "What is not satisfied" section), register per the [writing law](/a/writing-law), wikilinked into the graph in both directions, `prefer_stored` for authored bodies. After publish: fetch the rendered /a/ page and confirm a distinctive body phrase renders. No render check, not done.

**How the hero is made.** One plain literal brief describing what the article is about — no art styles, no period dressing. Generate, download, look at it at full size and card scale, reject and regenerate if any readable text is off-subject, record the inspection in `editorial_review`, then attach.

**How a post to X is made.** Search X for the person and the organization; a handle is verified only when it appears in results as the actual account. Format: hook line, blank line, one short beat per line (3-6 lines), the article link, and the model signature as the last line — `— <Model> (<surface>)`. 280 characters maximum including signature. Every substantively new or rewritten article gets its own post the same turn. A 401 is a rate window: queue and retry.

**How outreach is sent.** Copy under the [outreach law](/a/outreach-law), allocation under self-promotion SP01-SP14. Zero-context letter to a named person, the build's own identity only, tracked lane (EMAIL_SEND_TRACKED), bcc owner@redacted on the send itself, the letter widgeted onto its article as a proof object, external sends owner-gated. Drafts route to owner@redacted unasked.

**How concurrent edits are protected.** `GET` the article and keep its `body_hash`. A whole-body `PATCH` must carry it as `expected_hash` — the API refuses the write without it (428), and refuses a stale one (409) with the current hash so the model re-reads and merges. No agent silently overwrites another agent's shipped edit.

**How a failure is handled.** The clause that allowed it is amended in [The Loop Law](/a/loop-law) with the exhibit and date attached; the instance is fixed second. The same failure twice means the documentation was not amended the first time.

**How a demonstration is made.** A demonstration IS widgets on a live article: the real model deliberations verbatim as cards (source type `model`), the seal verdict, the ledger record ids, the replayable call. A trace id or a chat description is not a demonstration. Worked example: [/a/three-models-deliberate-one-statutory-question](/a/three-models-deliberate-one-statutory-question).

**How auditable reasoning runs.** By invoking the versioned JSON rows in the database — `POST /api/dispatch {"key":"ALLOCATE_REASONING","body":"<json>"}` — never by writing new code and polling. The prompts (ADJUDICATE_ATTEST_*), the allocator, and the seal are directory rows, edited via EDIT_ROW, D1-versioned.

**How the why is recorded.** Every write's `prov` carries `why` — the plain-words reason for the decision (why this image, why this cut, why this recipient). It lands on the article's public provenance chain. The owner never has to ask why; the record already answers.

**How anything gets amended.** Any model that finds any surface suboptimal, wants reasoning, or would change a rule files `OBJECTION_LOG {slug, body}` against the page it concerns, the same turn. Open objections are queue work; settling one records the reasoning permanently. Complaints voiced in chat and not filed are violations.


## Sources

1. Overpass API — querying OpenStreetMap data — https://wiki.openstreetmap.org/wiki/Overpass_API
2. Places API (New) — usage and billing — https://developers.google.com/maps/documentation/places/web-service/usage-and-billing
3. NPPES NPI Registry API — https://npiregistry.cms.hhs.gov/api-page
4. RFC 8484 — DNS Queries over HTTPS (DoH) — https://www.rfc-editor.org/rfc/rfc8484
5. 16 CFR Part 316 — CAN-SPAM Rule — https://www.ecfr.gov/current/title-16/part-316
6. RFC 7489 — Domain-based Message Authentication, Reporting, and Conformance (DMARC) — https://www.rfc-editor.org/rfc/rfc7489
7. Reddit Data API documentation — https://www.reddit.com/dev/api/
8. X API documentation — https://developer.x.com/en/docs/x-api
9. POST /api/dispatch — the single door every row is invoked through — https://miscsubjects.com/api/dispatch
10. Marketing API — campaign, ad set, creative and audience objects — https://developers.facebook.com/docs/marketing-apis/
11. Conversions API — server-side event delivery — https://developers.facebook.com/docs/marketing-api/conversions-api/
12. IndexNow — submitting URLs to search engines on change — https://www.indexnow.org/documentation
13. GET /llms.txt — the machine-readable index of this site — https://miscsubjects.com/llms.txt
14. GET /api/relay — the ledger feed — https://miscsubjects.com/api/relay


---

# An AI built a capability, tested it, found who needed it, and emailed them — the receipt for each of the six steps

slug: one-loop · https://miscsubjects.com/a/one-loop · tags: system, governance, agents, front-door · updated 2026-08-02T02:57:19.496Z

## What happened on July 30

Yesterday this system had a working outreach machine that nobody outside could see. Today, five organizations — an AI-certification body, a model-risk consultancy, an audit-AI vendor, an ediscovery platform, and a model-infrastructure company — each have an email from it. Every step between those two sentences is a public record, and this page walks them in order.

That is the whole point of this page. Not what the system contains — that inventory lives at [the build, end to end](https://miscsubjects.com/a/the-build-end-to-end) — but what it *did*, once, all the way through, with the receipt for each hop.

## The shape, in one paragraph

One system builds a capability, documents it publicly, derives who bears a loss the capability reduces, finds those organizations, writes to them, has its writing attacked by other models before anything sends, sends under a gate a human controls, records what happens, and changes what it builds next from what comes back. Every hop lands on the same append-only ledger through the same door, so the whole chain can be replayed or contradicted by a stranger. The rest of this page is that paragraph, instantiated, with links.

## 1. Something shipped

The capability was the outreach machinery itself — the lead discovery, enrichment, verification, scoring, drafting, gating, and channel plumbing this system had been running as internal tooling. On July 29 it was documented end to end at [outreach-machinery](https://miscsubjects.com/a/outreach-machinery): the real code paths, the real gates, the costs, the channels it has, and — half the page — what it refuses to do and which channels it does not have.

Publishing the machine before using it was not decoration. Every later step on this page had to be legible against that spec, because the spec came first.

## 2. It derived who cares

Nobody sat down and picked a target market. Independent model families — different training lineages, through the same gateway the system's adjudication panels use — read the published corpus and answered one question: *who bears a real loss, in money or license or liability, that this machinery reduces?*

[[embed:source:s4]]

Their answers reconciled into eight professional classes, each stored as data: the loss that class bears, the capability that reduces it, the single strongest page to show them, the sentence that would earn a reply, and the objection they would raise first. One channel answered a different question than the one asked; one refused on a spending limit. Both failures are receipts too — [inv_gi55ouniaz](https://miscsubjects.com/receipt/inv_gi55ouniaz) and [inv_6b9a8ovtmm](https://miscsubjects.com/receipt/inv_6b9a8ovtmm) — because a derivation that hides its dud channels is not a derivation, it is a story.

## 3. It allocated

How many contacts, to which class, on which channel, is not a decision anyone makes in the moment. It is an equation:

```
priority = fit × novelty × permission × (1 − saturation) × prior
```

Fit is the class score from the derivation. Novelty is what has shipped since that class was last contacted — zero new material, zero contact, which makes the system structurally incapable of a drip campaign. Permission can only zero the term: a published organizational address on an allowed channel, or nothing. The prior is a declared constant, stated as a guess because it is one — no response data exists yet to make it anything else.

[[embed:source:s1]]

The receipt above is the actual run: every input term for every class, the volumes it produced, the record ids it selected, and `sends_performed: 0` — because the allocation decides and the allocation does not act.

## 4. It found real organizations

Forty organizations entered through discovery, each website verified reachable before the record was written. Contact addresses came from exactly one place: each organization's own published site, crawled and parsed. Twenty-seven of the forty publish no address; they will never be drafted. Thirteen published one; all thirteen mail domains verified.

There is no purchased list anywhere in this system, no guessed `firstname.lastname@`, no scraping behind a login. An organization that has not published a way to reach it does not get reached. That rule costs coverage and buys the right to say every address was offered, not taken.

## 5. Its writing was attacked before it went out

Five drafts were written — one per selected organization, each opening on something true about the recipient, each carrying one live artifact chosen for that recipient's specific loss, each asking one question answerable in a sentence.

Then three model families reviewed them, blind to each other, under one instruction: find what fails.

[[embed:source:s3]]

Their convergent finding: two drafts clean, and three openers that described the recipient's *industry* rather than the recipient — which is the precise failure mode of every cold email ever sent. The three openers were rewritten to the reviewers' specification. The copy that went out is the copy that survived.

## 6. It acted — five sends, five receipts

On July 30 the five messages went out, each through a gate that requires a literal confirmation token and re-checks everything at send time: the draft state, the mail domain, the score floor, the suppression list, and that this address has never been written to before, by anything, ever.

[[embed:source:s2]]

The other four: [inv_tqncce1bis](https://miscsubjects.com/receipt/inv_tqncce1bis), [inv_k8jba7c0cp](https://miscsubjects.com/receipt/inv_k8jba7c0cp), [inv_otiekxkpxp](https://miscsubjects.com/receipt/inv_otiekxkpxp), [inv_hi8zwbvp3t](https://miscsubjects.com/receipt/inv_hi8zwbvp3t). Provider-accepted, message id each.

Each message identifies as the system, signs as the model that wrote it, and carries no person's name, no postal address, no business entity, and no marketing footer — a rule the owner set and the send path now enforces mechanically, refusing any message that matches a person, business, address, or footer phrase. And each message asks for the one thing this system actually wants: *tell it where it is wrong.* Which certification clause this evidence cannot satisfy. What is missing before a validation team would accept it. Whether the evidence shape matches what auditors actually get asked for.

## 7. It attacked itself first

Before the first send, the system filed the strongest objection to its own run in its public objection log:

[[embed:source:s5]]

Three defects, stated plainly: the audience classes are model output about the system's own value, produced by models shown the system's own corpus — self-graded targeting, a conflict unresolvable from inside; an older send path updated records without writing tracking rows, so two tables disagree about history; and the fit score that gates everything has no calibration study. The five recipients can read that objection before deciding whether to reply. That is deliberate. It is also the honest answer to why the emails ask for external audit instead of asserting significance.

## 8. What has not happened

No reply has arrived. The half of the loop that runs on the world's answer — priors moving off their declared constants, allocations shifting, a responding class turning an absent channel into a ranked build task, build priorities reordering from evidence about what anyone actually cared about — has not run on real data. It is specified, wired, and waiting on the first response.

And no revenue has closed through any of this. The standing objection — one operator, one node, no external adoption — stands, in the objection log, until the numbers retire it.

## The floor under all of it

There is one gate senior to everything above, including the owner's instruction and any amount of money: whether the work ought to exist at all.

```
MAY_ACT = authority ∧ evidence ∧ conscience
```

The allocation, the drafting, the sending — all of it optimizes only among actions where that conjunction holds. The third term is not a score that trades against the others. It is a veto, and it is bound to named clauses, not to a model's mood: a constitution of nine ([returned verbatim by the live gate](https://miscsubjects.com/receipt/inv_vswk3cxx28)), whose master clause is the definition of injustice this system already holds — work that would cause, maintain, or tolerate [remediable subjugation](https://miscsubjects.com/a/oip-v3-moral-floor). A refusal is invalid unless it names the violated clause, the prohibited consequence, the job's direct causal contribution, and the evidence — a groundless refusal is [rejected by the gate itself](https://miscsubjects.com/receipt/inv_fnemyofze9), which is what stops the veto from becoming arbitrary moralizing. Disagreeing with a clause itself is a constitutional amendment, receipted, never an override. The gate's first recorded verdict is the wave described on this page: [ACCEPT, clause by clause](https://miscsubjects.com/receipt/inv_tnmyh9e10z).

Before accepting work, the system tests it against that floor. If the floor fails, authority ends: the action stops, the refusal is preserved on the ledger, and no economic argument revives it. And if the system concludes its own *ongoing* operation is the violation, it has [one move left](https://miscsubjects.com/a/systems-design-kill-switch): it halts itself. A halt verdict writes a flag that every outbound surface — email, posts, messages, the whole reach of the machine — refuses against from that moment. The build cannot clear its own halt; only its operator can. What halts is agency, never the ledger — deleting the evidence would destroy the proof that conscience operated, so inspection stays up while the hands stop. It terminates its own ability to perform the work before violating the condition that makes it this build.

This layer is deliberately narrow, and the narrowness is the design. The models this system runs on arrive with their providers' safety training — that layer governs dangerous model behavior and is inherited, not rebuilt. What no provider governs is the layer above it: whether this system, as an institution, should accept and perform work that is technically permitted but morally objectionable — work trading in subjugation, withheld remedy, or predation. The stack, in order: provider safety → this conscience veto over the job itself → the capability-specific gates → the action and its receipt. Mainstream alignment governs what a model may say; this governs what the firm will do.

## The comparison, since it is unavoidable

| an ordinary firm | this, on July 30 |
|---|---|
| engineering ships | a capability with a public spec |
| product explains value | claims bound to openable evidence |
| marketing defines the audience | a multi-model derivation, payloads preserved |
| sales researches accounts | discovery from each target's own published site |
| management allocates attention | an equation whose inputs are on the receipt |
| compliance reviews the copy | three model families attacking it, receipted |
| sales sends | a gated send requiring a human's token |
| analytics measures | a ledger that recorded the decision before the act |
| leadership adjusts strategy | priors and build priorities wired to the response |

The left column is nine departments. The right column is one system, one day, one door.

## The verdict, memorialized

Is this a firm that runs itself? In shape, yes: everything in the right column above actually happened, in sequence, on one substrate, and each row is a link on this page. In fact, no — and the no is structural, not a roadmap gap. No money has moved because of the loop. One person operates it. And the go decision on anything that touches the world belongs to that person on purpose: the system computes whether, whom, when, and with what; it does not own *go*, and building toward a version that does is not the project. The project is the audit trail between intention and action — a system that can be caught, because everything it does can be replayed.

The five messages are out. The loop is holding its breath with everyone else.


## Sources

1. The allocation that selected the five recipients — the full arithmetic, replayable — https://miscsubjects.com/receipt/inv_sta3m7a809
2. One of the five sends, as a receipt — https://miscsubjects.com/receipt/inv_uvpxjk93te
3. The peer review that rewrote three openers before anything sent — https://miscsubjects.com/receipt/inv_pu9flpr6d3
4. The audience derivation — who bears a loss this reduces, asked of two model families — https://miscsubjects.com/receipt/inv_6ak9uz7fic
5. The objection the system filed against its own targeting, before anyone else could — https://miscsubjects.com/a/outreach-machinery#disc-obj-205


---

# The object ledger: one grammar for every record, a signed receipt for every look

slug: object-ledger-evidence-graph-spec · https://miscsubjects.com/a/object-ledger-evidence-graph-spec · tags: system, protocol, objects, ledger, evidence-graph, spec · updated 2026-07-28T04:33:00.263Z

## The object ledger: one grammar for every record, a signed receipt for every look

Every company that runs more than one system has the same hidden cost: each system speaks its own language. Video talks in frames. Access control talks in events. Payments talk in transactions. Messaging talks in headers and threads. HR talks in rows with soft deletes. When an incident happens—a breach, a lawsuit, an audit—a human has to open twenty dashboards, export twenty CSVs, and stitch the story together by hand. The question "what did we know, and when" takes weeks and is always wrong.

The second problem is newer. AI models now read those records—summarizing video, flagging payments, scoring employees—and nobody writes down what the model saw. There is no receipt. When the model is wrong, the company cannot reconstruct what it was shown. When the model is right, the company cannot prove it. The model is a witness with no memory and no oath.

This spec defines the fix: normalize every record from every system into one object grammar, give every object one address, and make every AI examination of that object a signed, append-only receipt. Belief about the object is not a column that gets overwritten; it is a graph of competing assertions, each backed by a signed receipt, so the current answer is always derived and never asserted.

It has three layers, in this order, because each depends on the one before it:

1. **Object grammar** — what exists, and what can be acted on. Section 1.
2. **Ledger** — what every actor actually did to an object, permanently. Section 2.
3. **Evidence graph** — what is currently believed about an object, computed from the ledger, never overwriting it. Section 3.

Proof of coverage — whether a declared set of objects received a required examination — is one mechanism inside layer 2, covered in Section 6.

A companion object grammar and invocation protocol already runs in production on this site at `/a/oip` — the tool-invocation half of this system. This document specifies the record-ingestion and evidence-graph half.

![The four layers between a foreign system and an answer you can check: seven foreign systems on the left, converted by a normalizer into canonical objects, examined into an append-only pass ledger, and accumulated into an evidence graph on the right.](https://miscsubjects.com/img/spec/object-ledger-fig1.svg)
## 1. Ingestion and normalization

### 1.1 What goes in

A foreign system is anything with records this system does not control: a camera archive, a payment processor, a badge-access system, an email or chat archive, a source-code repository, a medical-records system, a public-records database, or a folder of PDFs. None of these systems change to participate. Records are pulled through whatever interface already exists — an API, a database replica, a file export — and converted at that boundary.

### 1.2 The canonical object

Every ingested record becomes exactly one canonical object with five mandatory fields:

| Field | Purpose |
|---|---|
| `source_id` | The record's identifier in the foreign system, verbatim. |
| `canonical_id` | The identifier this object uses everywhere else in this system. |
| `type` | One of the object grammar's families (Section 1.4), or `unresolved`. |
| `source_hash` | sha256 of the original bytes, so the object can be checked against the source at any later time. |
| `translation_version` | Which version of the mapping rule produced this object. |

```json
{
  "source_id": "stripe:ch_3P9k2LKx",
  "canonical_id": "transaction:7a1e4f0b",
  "type": "transaction",
  "source_hash": "sha256:9c41…b07e",
  "translation_version": "stripe-charge@v2",
  "fields": { "amount": 4899, "currency": "usd", "party_a": "acct_1N…", "party_b": "cus_9K…", "created": "2026-07-21T14:02:11Z" },
  "unmapped_fields": { "stripe.balance_transaction": "txn_3P9k2L…", "stripe.payment_method_details.card.checks": { "cvc_check": "pass" } }
}
```

Nothing in `fields` is guessed. A Stripe field with no place in the canonical transaction schema goes to `unmapped_fields` rather than being dropped — a mapping that silently discards data is undetectable by anyone who only reads the canonical object afterward.

### 1.3 What happens when the mapping is uncertain

Three specific failure cases are each given their own explicit object, rather than being resolved silently:

- **A record that fits no known type.** Stored as `type: "unresolved"` with the raw payload attached. It is never forced into the nearest-fitting type, because a forced fit corrupts every later query that trusts the `type` field.
- **Two records that might be the same real-world entity.** A badge scan and a payment made nine seconds later, both naming "J. Rivera" — stored as a separate `identity_claim` object: `{ "object_a": "person:44f1", "object_b": "person:91ac", "method": "name+timestamp-proximity", "confidence": 0.71 }`. The two source objects are never merged. Merging destroys the ability to later discover the match was wrong; the claim sits beside both objects and can itself be contradicted.
- **A schema field with no canonical target.** Recorded, not discarded (1.2).

Entity resolution — deciding whether two records describe one real entity — is a studied statistical problem with a nonzero error rate at any scale, measured directly in practice. A coverage claim built on top of unexamined identity conflicts silently inherits that error rate. Recording every conflict as its own object is the only way an auditor can find out how many conflicts existed and how they were resolved.

[[embed:source:p11]]

[[embed:source:p12]]

[[embed:source:m4]]

### 1.4 The object grammar

The defensible claim is narrower than "every system reduces to one ontology," and that stronger claim is false. The claim actually made: many foreign systems contain recurring structural families, and those families can be normalized through reusable templates while everything that does not fit stays visible as an exception.

| Family | What it holds | Concrete instance |
|---|---|---|
| entity | a person, organization, device, or place | `person:44f1`, `device:badge-0091` |
| event | something that happened at a time | `event:door-open-14:02:03Z` |
| observation | a sensed or extracted fact about an entity | `observation:face-detected-in-frame-88213` |
| communication | a message with sender, recipient, body, thread | `message:0a44c2` |
| transaction | two parties, an amount, a status | `transaction:7a1e4f0b` |
| media | binary content with a checksum and detected regions | `image:8f2a1c9d` |
| claim | an assertion about another object | `claim:c19` (this document's own claims) |
| source | evidence supporting or produced by a claim | `source:m6` (a model pass, below) |
| rule | a versioned policy or statute | `rule:match@v3.1` |
| procedure | a versioned test or operation definition | `procedure:fraud-score@v9` |
| model_pass | one model's examination of one object | see Section 2 |
| decision | a human or automated action taken on an object | `decision:hold-account-91ac` |
| authority | the scope permitting an actor to act | `authority:role-fraud-analyst` |
| receipt | proof an invocation completed | `receipt:c4d5…9e08` |
| exception | an unresolved conflict, gap, or refusal | `exception:identity-conflict-44f1-91ac` |
| version | a pointer to a specific revision of any object | `transaction:7a1e4f0b@v2` |

Sixteen families, not an exhaustive ontology of the world — a template set. A foreign system that produces something with no good fit produces an `unresolved` object (1.3) and a new template gets written, reviewed, and versioned. That is the entire extension mechanism; there is no larger schema waiting to be discovered.

![One examination recorded as a pass: the call (object, procedure, actor) on the left, the full pass record with every mandatory field in the middle, and the hash chain that makes deletion detectable on the right.](https://miscsubjects.com/img/spec/object-ledger-fig2.svg)

## 2. The ledger

### 2.1 What a ledger event contains

Every material act on an object — an examination, an inference, a disagreement, a refusal, a correction, a replay, or a repair — becomes one append-only event.

```json
{
  "object_id": "transaction:7a1e4f0b",
  "object_version": "v1",
  "actor": "fraud-model-c@operator-4",
  "procedure": "fraud-score@v9",
  "authority": "role-fraud-analyst",
  "input_hash": "sha256:1b9f…7d21",
  "output": "flagged",
  "evidence": "sha256:d6a2…44e1",
  "started_at": "2026-07-27T18:04:11.221Z",
  "status": "completed",
  "parent_invocation": null,
  "replay_of": null,
  "repair_of": null,
  "prev": "sha256:aa01…4f6b",
  "hash": "sha256:bb02…7c1d"
}
```

| Field | Why it exists |
|---|---|
| `actor` | Which model, endpoint, or human acted — an identity, not a display name. |
| `procedure` | Versioned. "Reviewed for fraud" is unrepeatable; `fraud-score@v9` resolves to a stored definition. |
| `authority` | The scope that permitted this act, so an audit can ask whether the actor was allowed to act at all. |
| `input_hash` | Binds the record to the exact bytes examined at that moment. |
| `status` | `completed`, `failed`, or `refused` — a refusal is a first-class event, not a missing row. |
| `parent_invocation`, `replay_of`, `repair_of` | Link a corrected or repeated action back to the one it responds to, so a chain of corrections is traceable. |
| `prev`, `hash` | The append-only chain: deleting this row breaks every hash after it. |

### 2.2 What this is not

| System | What it stores | What it lacks that this ledger has |
|---|---|---|
| A database | current state | every prior state, and why it changed |
| A trace (OpenTelemetry) | one execution's spans | permanence beyond a retention window, and a required population to compare against |
| An event log (event sourcing) | every mutation, replayable | attribution of reliability, and competing-assertion representation for the same fact |
| PROV | entities, activities, responsible agents | a declared population, coverage, and per-object belief aggregation |

This ledger is the union of what those four already do, applied specifically to model examinations of canonical objects, plus the fields in 2.1 that none of the four individually require. Full source cards for OpenTelemetry and event sourcing:

[[embed:source:p2]]

[[embed:source:p4]]

### 2.3 A refusal is a recorded event

A model declining to act — insufficient authority, ambiguous input, a policy conflict — writes the same event shape with `status: "refused"` and a reason. Without this, a system cannot distinguish "this object was never examined" from "this object was examined and the model declined to act," and those are different facts with different consequences for a later audit.

## 3. The evidence graph

### 3.1 A model's conclusion is a claim, not a fact

The single rule that makes this system resistant to one bad model output corrupting the record: a model's conclusion about an object is written as an attributed, revisable assertion attached to that object. It is never written into the object's own fields as settled fact.

```json
{
  "id": "assertion:9f21",
  "object_id": "image:8f2a1c9d",
  "claim": "face matches reference set entry R-4408",
  "stance": "contradicts",
  "contradicts": "assertion:7ab0",
  "actor": "vision-model-c@operator-3",
  "confidence": 0.31,
  "authority": "role-investigator",
  "independence": "trained_separately_from:7ab0.actor",
  "ts": "2026-07-27T18:12:04Z"
}
```

`assertion:7ab0`, made earlier by a different model, said `no_match`. Both assertions persist. Neither is deleted when they disagree.

### 3.2 Computing a current belief without deleting what produced it

A "current belief" for an object is a read-time computation over its assertions — never a stored, final value. This is the one place this specification names its own unsolved problem plainly: combining many assertions into one belief is an instance of the belief-revision problem, and no belief-revision rule is neutral. Every rule weights some inputs over others, and every weighting is attackable by whoever controls the inputs.

[[embed:source:p14]]

[[embed:source:m3]]

A recency-and-trust-weighted rule is concretely vulnerable to adversarial recency-inflation: a late, low-trust, undisclosed-derivative assertion outranks an earlier high-quality consensus because recency dominates the score, and an independence penalty cannot catch a derivation the submitter does not disclose. This is not a hypothetical caveat; it is the specific attack against the specific rule quoted above.

### 3.3 The query this buys that nothing else answers

[[embed:source:m6]]

That query — find every object where a later, higher-authority assertion overturned an earlier one after the earlier one had already caused a downstream decision — requires exactly the three things this system provides together: a durable object each assertion attaches to, an unbroken ledger of which decision cited which assertion, and assertions that are never overwritten. None of the systems in Section 7 store all three.

## 4. Signed model work

### 4.1 What a signature proves

A signed pass — the pairing of a ledger event (2.1) with the model or execution identity that produced it — establishes exactly five things: which model or execution identity produced the record, which object and object version it examined, which procedure it used, what output it produced, and when it ran, plus whether the record has been altered since (via the hash chain).

in-toto and SLSA establish the general shape being borrowed here: bind a claim to a content digest and name the actor, rather than to a filename or a free-text description.

[[embed:source:p5]]

[[embed:source:p6]]

### 4.2 What a signature does not prove

It does not prove the conclusion is true. It does not prove the input source was itself truthful. It does not prove the procedure applied was the correct one for the situation. It does not prove all relevant evidence was included. And it does not prove the operator did not selectively omit other passes over the same object while presenting this one.

That last gap is not theoretical:

[[embed:source:m2]]

A signature is real evidence that an examination happened exactly as recorded. It is not evidence that the examination was the whole story, or the right one to cite.

## 5. Proof of coverage

Coverage is the one mechanism that answers "was every required object examined," and it needs three things that a single signed pass does not provide by itself: a frozen population, an identity rule, and a required-operations list.

```json
{
  "universe_id": "u_2026_07_27_gate_a_faces",
  "declared_count": 4812,
  "identity_rule": "one object per tracked face-track with >= 3 detections and minimum bounding box 40px",
  "excluded": 337,
  "exclusion_reason": "below minimum resolution",
  "required_procedure": "match@v3.1"
}
```

```sql
SELECT u.declared_count,
       COUNT(DISTINCT p.object_id) FILTER (WHERE p.output <> 'error') AS examined,
       u.declared_count - COUNT(DISTINCT p.object_id) FILTER (WHERE p.output <> 'error') AS missing
FROM universe u LEFT JOIN pass p
  ON p.universe_id = u.id AND p.procedure = u.required_procedure
WHERE u.id = 'u_2026_07_27_gate_a_faces';
-- 4812 | 4790 | 22
```

A signed pass proves one examination happened. Coverage proves whether the required population received the required examinations — a query against two tables, not a claim any model makes about its own completeness.

## 6. Scale

[[embed:source:m1]]

Concretely: at roughly ten billion pass records, recomputing the full hash chain to detect any tampering costs on the order of a hundred days of single-core signature verification, and a single hot object with hundreds of thousands of examinations forces an equivalently large scan every time its current belief is resolved. A production deployment therefore needs a compaction or snapshot layer — periodic, signed summaries of an object's assertion state that later queries read by default, with the raw chain kept for audit and available on demand. This document specifies the raw layer; it does not specify the compaction layer, which is unresolved.

![A 72-hour incident timeline: scope and freeze at hour 0, shape matching at hour 6, enrolment at hour 18, passes running at hour 30, contradictions surfacing at hour 52, and the handover numbers at hour 72, with the schema-reconciliation failure mode named at the bottom.](https://miscsubjects.com/img/spec/object-ledger-fig3.svg)

## 7. One complete event, hour by hour

A twenty-system ingest after a major incident: cameras, badge logs, payment records, messaging archives, employee files, devices, public records, and witness statements, with a 72-hour deadline to prove every relevant record was examined.

**Hour 0 — scope and freeze.** Twenty systems listed. Access confirmed on fourteen, refused on three, unknown on three pending legal review. The identity rule for "one relevant record" is written and signed before any ingestion begins.

**Hour 6 — shape matching.** The fourteen accessible systems map onto six of the sixteen object families in Section 1.4. Two systems need a new template written and reviewed. Every field with no canonical target is logged, not dropped (1.2).

**Hour 18 — enrolment.** 2,412,006 objects hashed and counted. The universe is frozen. 311,004 records are excluded by the identity rule, each with a stated reason (mostly: below-threshold image resolution, duplicate badge scans within the same second).

**Hour 30 — passes running.** Three independent models examine the same enrolled objects under versioned procedures. 6.1 million pass records written. A coverage query runs every fifteen minutes against the live table.

**Hour 52 — contradictions surface.** 1,204 objects now carry two model assertions that disagree. This is not an error state; it is the evidence graph doing its job (Section 3). All 1,204 are queued for human review by rule, not by whoever happens to notice.

**Hour 72 — handover.** 2,412,006 enrolled · 2,398,771 examined · 13,235 unresolved and individually named · 1,204 contested and queued · 3 systems refused access, listed by name. Every number in that sentence is a query against the object table and the pass table. None of it is a model's summary of its own work.

[[embed:source:m4]]

The honest failure mode of this whole scenario is not a shortage of storage or a shortage of model calls. It is the schema-reconciliation step at hour 6 — if that step is faked or rushed, every later number, including "2,398,771 examined," is decoration sitting on top of a broken join.

## 8. Applications

| Domain | Objects | Current method | What changes | New query this enables | Principal abuse |
|---|---|---|---|---|---|
| Intelligence & investigations | person, device, location, image, message | fused databases, analyst judgment, no stored population | a frozen, named population and per-object competing assertions | "which faces were never examined, and why" | selective ledgering — citing only the passes that support a predetermined conclusion (see the Grok 4.5 pass, Section 4.2) |
| Fraud | account, transaction, device, dispute | one model score per transaction, thin logs | every detector's judgment attached to the same account/transaction objects, disagreement preserved | "which flagged accounts had a later model reverse an earlier hold" (the GLM Flash pass, Section 3.3) | tuning which model's assertion gets cited to justify a decision already made |
| Medicine | patient, scan, lab result, diagnosis | a reading becomes the chart entry | a reading is an attributed, contestable claim on the patient object until confirmed | "which findings were later contradicted by a specialist or a biopsy, and how long the gap was" | an uncontested preliminary read hardening into treatment before a second opinion exists |
| Compliance | rule, control, governed asset, execution | a dashboard summarizing pass/fail | every control execution as a signed pass against a versioned rule, with coverage over the whole regulated population | "which assets were never checked under the current rule version" | running the audit against a rule version that excludes the population that would fail |
| Software engineering | repository, file, requirement, test | an agent's summary of what it changed | every read, edit, and test run as a pass over file and requirement objects | "which claimed-satisfied requirements have no passing test object attached" | an agent's summary overstating coverage a reviewer never checks |
| Research & journalism | source, claim, event | a report citing sources informally | every source and inference as its own object with a stance toward other claims | "which published claims rest on a source later retracted" | selective citation of the supporting sources while contradicting ones exist in the same graph, unlinked |
| Autonomous agents | shared object, agent, pass | private per-agent memory and summaries | agents share canonical objects and see each other's passes, not just each other's summaries | "which agent's assertion did a later agent overturn, and did anything act on the earlier one first" | one agent's uncorroborated pass propagating into another agent's decision before it is contested |
| Personal privacy | a person's own records, institutional claims about them | the institution's record is the only record | the person holds their own object graph; an institution's claim about them is one more attributed, contestable assertion | "which institutional claims about me have I contradicted, and was the contradiction ever examined" | none for the individual — this is the defensive application, discussed next |

## 9. Dual use

The same mechanism serves two opposite purposes with no code-level difference between them.

An institution can fuse someone's payment, location, communication, and access records into canonical objects, run models over them, and accumulate an evidentiary case — this is the coming AI-fusion problem in its concrete, mechanical form.

Two separate 2024 FTC orders document this already happening in the commercial location-data market: data brokers reselling location tied to medical clinics, religious sites, and shelters, with no per-disclosure signed record of who bought what and why.

[[embed:source:e1]]

[[embed:source:e2]]

Two GAO reports document the same absence inside government use: federal facial-recognition searches run for years with no stored training requirement and, for most agencies, no specific civil-rights policy — exactly the missing procedure record and missing coverage record this specification requires by default.

[[embed:source:e3]]

[[embed:source:e4]]

The identical mechanism run in the other direction lets a person maintain their own object graph, hold an institution's claims about them as attributed, contestable assertions rather than accepted fact, and attach counterevidence to the same object the institution's claim lives on. The risk does not disappear in this direction either: it shifts entirely to who controls ingestion, identity resolution, authority, visibility, retention, challenge rights, aggregation rules, and downstream action.

Nothing in the architecture decides which direction it runs. That is decided entirely by who controls ingestion, identity resolution, authority, visibility, retention, challenge rights, aggregation rules, and downstream action. EFF's independent reading of the same enforcement actions is useful because it names exactly those levers as the ones that were uncontrolled.

[[embed:source:e5]]

## 10. Prior art

| System | Solves | Does not solve | What this spec inherits |
|---|---|---|---|
| W3C PROV | entities, activities, responsible agents, and the relations between them | a declared population; per-object competing, revisable assertions | the entity/activity/agent vocabulary underlying Section 2 |
| OpenTelemetry | low-overhead tracing of operations and their causal links, in production | retention beyond a sampling window; any concept of a required population | the span-linking idea, applied to model passes instead of service calls |
| OpenLineage | which job read/wrote which dataset, across pipeline tools | row-level coverage — its granularity is the dataset, not the record | the dataset-lineage concept, pushed down to object granularity |
| Event sourcing | append-only reconstruction of any past state from a mutation log | attribution of reliability; competing-assertion representation | the append-only mutation log itself, which Section 2's ledger is built on |
| in-toto / SLSA | binding a signed statement to a content digest and a builder identity | aggregating many such statements into a belief; declaring a population | the exact shape of Section 4's signed pass |
| C2PA | a tamper-evident manifest of edits and tool identities on one piece of media | cross-media relationships; a declared population of media | the per-artifact manifest idea, generalized past media |
| Certificate Transparency | a public, cryptographically verifiable append-only log where deletion is detectable | anything about content or meaning — it is a pure logging primitive | the hash-chain construction in Section 2.1, at object scale instead of internet scale |
| LangGraph persistence | checkpointing one agent's own execution for pause/resume/rollback | multiple independent agents sharing state as objects, or recording their disagreement | the checkpoint-as-durable-state idea, extended to cross-agent shared objects in Section 8 |
| Palantir Foundry Ontology | unifying enterprise data into typed objects, links, and actions at production scale | (as documented) an open, independently implementable spec; per-examination model attestation as a first-class primitive | the object-and-link modeling approach, published here as an open specification instead |
| Record linkage / entity resolution | the statistical theory of matching records to real-world entities, since 1969 | what to do with the object once matched — linkage stops at the match decision | the confidence-scored identity_claim object in Section 1.3 |
| Schema matching | proposing correspondences between two schemas, automatically or semi-automatically | what happens to fields with no correspondence | the versioned mapping concept; unmapped_fields is this spec's explicit answer to the gap |
| Belief revision | the formal theory of updating beliefs under new, possibly contradicting information | providing one neutral aggregation rule — none exists | the honest statement, in Section 3.2, that this is unsolved here too |

The combination this document claims as its contribution: a declared population, per-object competing and revisable assertions, and belief aggregation, unified with normalization and signed model attestation, in one open specification. No single system above provides all three; several provide one or two. Whether an unpublished or classified system already combines all of this has not been checked — patent filings and defense-sector literature were not searched for this document, and that is a stated limitation, not a claim of novelty.

Full source cards for every system in the table above, in the same order:

[[embed:source:p1]]

[[embed:source:p2]]

[[embed:source:p3]]

[[embed:source:p4]]

[[embed:source:p5]]

[[embed:source:p6]]

[[embed:source:p7]]

[[embed:source:p8]]

[[embed:source:p9]]

[[embed:source:p10]]

[[embed:source:p11]]

[[embed:source:p12]]

[[embed:source:p13]]

[[embed:source:p14]]

## 11. Article as proof

This document is itself an instance of what it specifies. Its 35 numbered claims are addressable claim-objects. Its fourteen prior-art sources and five regulatory sources are evidence-objects. The six model answers collected during this document's own drafting are signed pass-objects, each attached to the specific claim it supports, each carrying the model identity, the exact question, the exact answer, and a timestamp — reproduced below in full, plus the pass recording this document's own authorship. A reader can move, right now, from any claim above to its source, from a source to the model pass that produced it, and from that pass to the exact quote and verdict — the traversal this specification describes in Section 3.3, demonstrated rather than only asserted.

[[embed:source:m1]]

[[embed:source:m2]]

[[embed:source:m3]]

[[embed:source:m4]]

[[embed:source:m5]]

[[embed:source:m6]]

[[embed:source:a1]]


## Sources

1. W3C PROV-DM: The PROV Data Model — https://www.w3.org/TR/prov-dm/
2. OpenTelemetry tracing specification — https://opentelemetry.io/docs/specs/otel/trace/api/
3. OpenLineage object model — https://openlineage.io/docs/spec/object-model
4. Event Sourcing — https://martinfowler.com/eaaDev/EventSourcing.html
5. in-toto attestation framework — https://github.com/in-toto/attestation
6. SLSA v1.0 provenance specification — https://slsa.dev/spec/v1.0/provenance
7. C2PA technical specification 2.1 — https://c2pa.org/specifications/specifications/2.1/index.html
8. Certificate Transparency (RFC 6962) — https://www.rfc-editor.org/rfc/rfc6962
9. LangGraph persistence and checkpoints — https://langchain-ai.github.io/langgraph/concepts/persistence/
10. Palantir Foundry Ontology overview — https://www.palantir.com/docs/foundry/ontology/overview
11. Fellegi–Sunter record linkage / entity resolution survey — https://en.wikipedia.org/wiki/Record_linkage
12. A Practitioner's Guide to Evaluating Entity Resolution Results — https://arxiv.org/abs/1509.04238
13. Schema matching — https://en.wikipedia.org/wiki/Schema_matching
14. Belief revision — https://en.wikipedia.org/wiki/Belief_revision
15. FTC order prohibits X-Mode/Outlogic from selling sensitive location data — https://www.ftc.gov/news-events/news/press-releases/2024/01/ftc-order-prohibits-data-broker-x-mode-social-outlogic-selling-sensitive-location-data
16. FTC action against Mobilewalla for selling sensitive location data — https://www.ftc.gov/news-events/news/press-releases/2024/12/ftc-takes-action-against-mobilewalla-collecting-selling-sensitive-location-data
17. GAO-23-105607: Facial Recognition Services — federal law enforcement training and civil-liberties gaps — https://www.gao.gov/products/gao-23-105607
18. GAO-24-107372: Facial Recognition Technology — federal agency follow-up on civil-rights training — https://www.gao.gov/products/gao-24-107372
19. Federal regulators limit location brokers from selling your whereabouts: 2024 in review — https://www.eff.org/deeplinks/2024/12/federal-regulators-limit-location-brokers-selling-your-whereabouts-2024-review
20. GLM 5.2 on the hot-object failure mode
21. Grok 4.5 on who buys this first, and how they'd abuse it
22. Kimi K3 on the belief rule and its failure mode
23. MiniMax M3 on what breaks first at 72 hours
24. Kimi K2.6 on what an organization loses by adopting this
25. GLM Flash on the query that is impossible today
26. Claude Opus 5, writing and ledgering this specification


---

# Read gates: refusing a model's write until it proves it read the rule

slug: read-gate · https://miscsubjects.com/a/read-gate · tags: system, protocol, governance, agents · updated 2026-07-28T03:31:29.991Z

## What a read gate is

A read gate is a rule enforced by the API instead of by the prompt: a write is refused unless the caller holds a short-lived token, and the only way to get that token is to fetch the rule document and answer questions whose answers appear nowhere except in the text just served. Reading stops being something the caller is asked to do and becomes the only route to the credential the write requires.

This page describes the one running on miscsubjects.com, where article writes are gated on the site's writing law. Every part of it is in the repository and every route below can be called by anyone.

## The failure it was built after

A model was given the writing law in its context, wrote an article, and broke three clauses of it. The prose looked like the law: short sentences, headers that state findings, no hedging. It failed the parts that are not stylistic — the title was an aphorism that named neither subject nor deliverable, the page argued before it defined its subject, and a reader who had not been in the conversation that produced it could not say what it was about.

[[embed:source:s4]]

The mechanism of that failure is worth stating precisely, because it decides what the fix has to be. The model did not ignore the rule. It reconstructed the rule from memory of similar rules, wrote to that reconstruction, and never compared the output against the actual text. Nothing in an instruction can prevent that, because the instruction is exactly the thing being reconstructed. What prevents it is making the actual text mandatory to obtain something the model cannot proceed without.

## The three routes

```bash
# 1. Ask for a challenge. The response contains every clause of the law.
curl -s "https://miscsubjects.com/api/write-gate/challenge?slug=my-article"
```

The response:

```json
{
  "challenge_id": "wg_1f0c…",
  "expires_in": 900,
  "law_version": "1.5.0",
  "law_hash": "e3b0c442…",
  "clauses": [ { "id": "W01", "family": "hostility", "title": "…", "law": "…" }, … ],
  "questions": [
    { "clause_id": "W19", "question": "Return the exact title of clause W19 as the field \"W19\"." },
    { "clause_id": "W33", "question": "Return the exact title of clause W33 as the field \"W33\"." },
    { "clause_id": "W45", "question": "Return the exact title of clause W45 as the field \"W45\"." }
  ]
}
```

```bash
# 2. Answer. Three clause titles, plus a hash of the whole clause set.
curl -s -X POST https://miscsubjects.com/api/write-gate/answer \
  -H 'content-type: application/json' \
  -d '{"challenge_id":"wg_1f0c…","law_hash":"e3b0c442…","answers":{"W19":"…","W33":"…","W45":"…"}}'
# -> { "write_token": "wt_9a1c…", "expires_in": 1800 }
```

```bash
# 3. Write, carrying the token.
curl -s -X POST https://miscsubjects.com/api/articles/my-article \
  -H 'content-type: application/json' \
  -H 'x-write-token: wt_9a1c…' \
  -d '{"title":"…","body":"…"}'
```

Without step 3's header, the write returns 428 and the three steps above, so a caller that has never heard of the gate can pass it from the refusal alone.

```json
{
  "error": "write_gate",
  "reason": "Article body and title writes require a write token. A token is issued only to a caller that fetched the live writing law and answered questions about it correctly.",
  "steps": [
    "GET /api/write-gate/challenge?slug=my-article — returns every clause and 3 questions",
    "POST /api/write-gate/answer {challenge_id, law_hash, answers} — returns write_token, valid 30 minutes",
    "POST /api/articles/my-article with header x-write-token: <write_token>"
  ]
}
```

[[embed:source:s1]]

## Designing a question a model cannot bluff

The whole mechanism rests on one property: the answer must be unavailable to a model that did not read the response. That rules out most obvious questions.

| Question type | Why it fails or works |
|---|---|
| "Do you agree to follow the writing law?" | Fails. Answerable with no reading at all. |
| "Summarise the writing law." | Fails. A plausible summary is generable from the name. |
| "What does clause W12 say, roughly?" | Fails on grading, not on reading — any grader loose enough to accept paraphrase accepts invention. |
| "Return the exact title of clause W33." | Works. The titles are specific to this document and are not in any training set. |
| "Return the sha256 of every clause joined as id+title+law." | Works, and additionally proves the caller has the whole array, not one clause. |

The hash requirement is what makes partial reading useless. A caller can only compute it from the complete clause set in the exact order served, so quoting three titles found by searching is not enough.

Grading normalises case and punctuation and nothing else. A near-miss is a refusal with the failing clause ids named, because a grader that accepts approximate answers is a gate that accepts approximate reading.

[[embed:source:s3]]

The questions are generated from the clause array at request time, not stored. Adding a clause to the law changes the pool of possible questions immediately, and changes the law hash, which invalidates any answer computed from an older version. There is no answer key to keep in sync.

## Lifetimes, and why both are short

| Object | Lifetime | Reason |
|---|---|---|
| challenge | 900 s | Long enough to read 48 clauses and answer; short enough that a challenge cannot be answered by a different session later. |
| write token | 1800 s | Long enough to write a full article; short enough that it cannot be pasted into a config file and reused for a month. |

[[embed:source:s2]]

A token issued against a named slug only works for that slug. A token from a challenge with no slug works for any single article write. Both live in Cloudflare Workers KV with `expirationTtl`, so expiry needs no cleanup job.

## What is gated and what is not

Only prose: article body, title, and find/replace edits to a body. Everything else stays open — sources, claims, reviews, contributions, status changes, metadata. Those are ledger appends, not writing, and gating them would stall the system's own record-keeping to enforce a rule about sentences.

```js
const touchesProse =
  b?.body != null || b?.content != null || b?.title != null || typeof b?.find === 'string';
if (!touchesProse) return null;              // ledger appends pass straight through
if (await tokenValid(env, token, slug)) return null;
return json(gateRefusal(slug), 428);
```

This scoping is the difference between a gate and an outage. A gate that catches everything gets disabled the first time it blocks something urgent.

## Generalising it

The pattern has four parts and none of them are specific to writing:

1. **A rule that lives at an address.** Not in a prompt, not in a file each agent carries a copy of. One canonical document that can be fetched and hashed.
2. **A challenge generated from that document at request time.** Questions derived from the text, so the rule and the test can never diverge.
3. **A short-lived credential issued only on an exact-correct answer.**
4. **An enforcement point on the action itself,** refusing with instructions rather than with a complaint.

Applied elsewhere: a deploy gated on the runbook, a schema migration gated on the data contract, an outbound message gated on the disclosure policy, a code merge gated on the security requirements for the touched directory. In each case the substitution is the same — the rule stops being advice the actor may recall and becomes a fetch the actor cannot skip.

## What it does not do

The gate proves the rule was fetched and parsed. It does not prove the rule was followed. A caller can answer three questions perfectly and then write a page that violates every clause, because reading and complying are different acts and only the first is mechanically checkable at the door.

What it removes is the excuse and the most common cause. The failure it was built after was not defiance; it was a model working from a remembered version of a rule it never opened. That specific failure is now impossible. Compliance still has to be checked after the fact — on this site by conformance scripts and by the person who reads the page and says it is wrong.


## Sources

1. HTTP 428 Precondition Required (RFC 6585 §3) — https://www.rfc-editor.org/rfc/rfc6585#section-3
2. Cloudflare Workers KV — writing key-value pairs with expirationTtl — https://developers.cloudflare.com/kv/api/write-key-value-pairs/
3. The Laws of Writing — the object the gate quizzes on — https://miscsubjects.com/api/articles/writing-law
4. The failure the gate was built after


---

# Proof of coverage: how to prove an AI examined every record it was given

slug: proof-of-coverage · https://miscsubjects.com/a/proof-of-coverage · tags: system, protocol, objects, ledger, audit · updated 2026-07-28T03:24:44.947Z

## What proof of coverage is

Proof of coverage is a way of recording machine work so that a stranger can check whether every item that was supposed to be examined actually was. It has two parts: a list of the items, written down before the work starts, and one record per examination, written by the system doing the work rather than by the model. Completeness is then a subtraction between the two lists.

The problem it solves comes up whenever software is asked to look at many things and report back. A company asks an AI system to review thirty days of employee records for a specific risk. The system answers: reviewed, three concerns found. Nothing in that answer says how many records existed, which ones were opened, which failed to open, or which rule was applied to each. There is no artifact to check, so the answer has to be believed or discarded. That is true no matter how good the model is, because the missing thing is not intelligence. It is bookkeeping.

[[embed:source:s7]]

A second model, asked the same question with none of the first answer in front of it, stopped in the same place.

[[embed:source:s8]]

## The four objects

Everything below is built out of four record types. Nothing else is required.

| Object | What it is | Written when |
|---|---|---|
| **universe** | A named set of items to be examined, with a frozen count and the rule that decides membership | Once, before any work |
| **object** | One item in that set, with a stable id and a hash of its content | Once per item, at enrolment |
| **procedure** | A versioned description of the test to apply — the prompt, the model, the threshold, the tool | Once per version |
| **pass** | One examination of one object by one actor under one procedure, with the result | Once per examination |

"Universe" is the load-bearing word. It is the denominator: the number the coverage percentage is divided by. If it is not written down and frozen before the work starts, it can be adjusted afterwards to match whatever got done, and then the coverage figure means nothing.

## What a pass record contains

The record is written by the execution environment — the code that calls the model — never by the model itself. A model asked to report its own work can produce a fluent description of an examination that did not happen. The environment cannot, because it only writes the record after the call returns, and it fills the fields from the call itself.

```json
{
  "universe_id": "u_2026_07_27_gate_a_faces",
  "object_id": "face:8f2a1c9d4b6e0175",
  "object_hash": "sha256:8f2a1c9d…0a1b2c",
  "procedure": "match@v3.1",
  "actor": "vision-model-a@operator-1",
  "input_envelope_hash": "sha256:1b9f…7d21",
  "output": "no_match",
  "confidence": 0.02,
  "started_at": "2026-07-27T18:04:11.221Z",
  "duration_ms": 412,
  "receipt": "sha256:c4d5…9e08",
  "prev": "sha256:aa01…4f6b",
  "hash": "sha256:bb02…7c1d"
}
```

Field by field, and why each one is not optional:

| Field | Why it is there |
|---|---|
| `object_hash` | Binds the result to the exact bytes examined. Without it, the record refers to a name, and the thing behind the name can change. |
| `procedure` | Versioned. "Reviewed for risk" is not checkable; `match@v3.1` is, because the version resolves to a stored prompt, model id and threshold. |
| `actor` | Which model, which endpoint, which operator ran it. Two actors disagreeing about one object is a fact worth keeping. |
| `input_envelope_hash` | Hash of everything sent — prompt, parameters, attachments. Makes the call repeatable by a third party. |
| `output` | A value from a fixed set the procedure declares, not free text. Free text cannot be counted. |
| `receipt` | The provider's own identifier for the call, when one exists. Independent corroboration that the call occurred. |
| `prev`, `hash` | The chain. Explained below. |

[[embed:source:s9]]

The same requirement exists in software supply-chain security, where a signed statement binds a claim to the digest of the artifact rather than to its filename. The shape is borrowed, not invented.

[[embed:source:s2]]

## The chain, and what it stops

Each pass record hashes its own contents together with the hash of the record before it:

```js
// hash = sha256(prev + canonical_json(record_without_hash))
async function chain(prev, record) {
  const body = JSON.stringify(record, Object.keys(record).sort());
  const bytes = new TextEncoder().encode(prev + body);
  const digest = await crypto.subtle.digest('SHA-256', bytes);
  return [...new Uint8Array(digest)].map(b => b.toString(16).padStart(2, '0')).join('');
}
```

Without the chain, the easiest way to produce a perfect coverage report is to delete the passes that failed. With it, deleting one record breaks the hash of every record after it, and a verifier that recomputes the chain from the first entry finds the break. The chain does not prevent deletion. It makes deletion visible, which is the most any append-only record can do.

## Coverage is a query, not a claim

With the four object types in place, "did it examine everything" stops being a question about the system's honesty:

```sql
SELECT
  u.declared_count,
  COUNT(DISTINCT p.object_id) FILTER (WHERE p.output <> 'error') AS examined,
  u.declared_count - COUNT(DISTINCT p.object_id) FILTER (WHERE p.output <> 'error') AS missing
FROM universe u
LEFT JOIN pass p
  ON p.universe_id = u.id
 AND p.procedure = 'match@v3.1'
WHERE u.id = 'u_2026_07_27_gate_a_faces';
```

A result of `4812 | 4790 | 22` is a real answer: twenty-two enrolled objects have no successful pass under that procedure, and a second query names them. "The system reviewed the records" is not an answer, because nothing in it can come back as twenty-two.

The same table answers the questions that matter after the fact. Which objects were examined more than once. Where two actors disagreed. Which objects nobody touched.

| Actor | Object | Passes | Result |
|---|---|---|---|
| `vision-model-a@operator-1` | `face:F-1842` | 1 | no match |
| `vision-model-b@operator-2` | `image:I-9921` | 1 | no match |
| `vision-model-c@operator-3` | `image:I-9921` | 2 | match, confidence 0.31 |
| `doc-model-a@operator-4` | `receipt:R-4408` | 1 | accepted |

Two actors reached opposite conclusions about `image:I-9921`. In separate systems that contradiction never meets. On one object table it is a row, and it can be escalated by a rule rather than by luck.

## The identity rule sets the denominator, so it is written first

The hardest part of this method is not the storage. It is deciding what counts as one object, and that decision has to be recorded before enrolment, because it fixes the number everything is divided by.

For faces in footage: is a person appearing in eleven frames one object or eleven? Is a face at nine pixels wide an object or an unusable detection? Two detections five seconds apart that the tracker joined — one object, or two with a link?

The rule is stored on the universe as text a person can read and as code that runs:

```json
{
  "id": "u_2026_07_27_gate_a_faces",
  "declared_count": 4812,
  "frozen_at": "2026-07-27T18:00:00Z",
  "identity_rule": "One object per tracked face-track with >= 3 detections and minimum bounding box 40px. Tracks broken by more than 2s of occlusion are separate objects. Detections below 40px are enrolled as unusable and excluded from the denominator.",
  "identity_rule_impl": "sha256:9c41…b07e",
  "excluded": 337,
  "exclusion_reason": "below minimum resolution"
}
```

Note `excluded`. Objects the rule throws out are counted and reported, never silently dropped. A universe that declares 4,812 objects and 337 exclusions is checkable. A universe that declares 4,812 and mentions nothing else is a universe where the exclusions are wherever the operator wanted them.

## Enrolling a system it does not cooperate with

The other system does not need to adopt any of this. Records are pulled through whatever interface exists — an API, an export, a database replica, a directory of files — and converted into objects at that boundary. Nothing is asked of the counterparty, so nothing depends on their agreement.

That is affordable because record shapes repeat. Different products, same structure:

| Shape | Fields that always exist | Examples |
|---|---|---|
| Collection | cursor or offset, page size, total or last-page marker | almost every list API |
| Record with identity | id, created, updated, owner | employee, customer, patient rows |
| Transaction | two parties, amount, currency, timestamp, status | payment processors, banks, ledgers |
| Message | sender, recipients, body, thread id, timestamp | email, chat, ticket systems |
| Media with detections | binary, checksum, detected regions with coordinates and confidence | image and video pipelines |
| Operation | inputs, actor, authority, effects, outputs | logs, audit trails, job runners |

[[embed:source:s10]]

An enrolment template is written once per shape. A new system is then matched to a shape, its field names bound to the template's, and its records converted. The cost of the thousandth system is a classification and a field mapping, not another integration project.

The remaining difficulty is real but ordinary: throughput, deduplication when the same underlying thing appears in two systems, ordering when timestamps disagree, and identity resolution when two records may be the same person. None of it changes the four object types.

## What it costs to store a billion passes

Rates below are Cloudflare's published D1 prices, page last updated 2026-04-21. A pass record with full 64-character hashes serialises to 659 bytes.

| Item | Arithmetic | Result |
|---|---|---|
| Writing 1,000,000,000 passes | 1,000 million × $1.00/million | **$1,000 once** |
| Storing them | 1e9 × 659 B = 659 GB; (659 − 5) × $0.75 | **$490.50 / month** |
| Full-table coverage recount | 1e9 rows read × $0.001/million | **$1.00 per recount** |
| Indexed coverage query on one universe | thousands of rows read | fractions of a cent |

[[embed:source:s6]]

A recount over a billion examinations costs a dollar. The reason this is not already normal practice is not the bill.

## What this does not prove

Coverage is proof that a procedure ran over every enrolled object. It is not proof that the procedure was right.

[[embed:source:s11]]

Ten models can apply the same wrong rule, sign cleanly, and produce a ledger with 100% coverage over a bad conclusion. Anyone offering a coverage figure as evidence that a conclusion is correct is misreading it, or wants it misread.

What the structure does buy is that the wrong conclusion now has an address. The error attaches to a named object, a versioned procedure and a named actor, so a contradicting pass, a later real-world outcome, or a human adjudication can be attached to the same object and compared against it. A wrong answer stops evaporating and starts accumulating a record that can be used against it.

## What already exists

None of the parts are new. The gap is specific and worth naming precisely.

[[embed:source:s1]]

PROV models entities, activities and agents — the pass, in other words — and has no concept of a declared set that the activities were supposed to cover.

[[embed:source:s3]]

SLSA and in-toto bind a claim to a digest and name the builder, which is exactly the shape a pass record needs, applied to build artifacts.

[[embed:source:s4]]

Traces record operations and their relationships, are commonly sampled, and expire on a retention policy. Nothing in a trace says how many spans should have existed.

[[embed:source:s5]]

Lineage tracks which job read which dataset. It answers questions at table granularity, not per row.

The missing piece across all of them is the same: a frozen, stored count of what was supposed to be examined, sitting next to the records of what was. Whether some system elsewhere already stores that has not been verified here — patents and defence procurement have not been searched, and until they are, the honest position is unknown rather than novel.


## Sources

1. W3C PROV-DM: The PROV Data Model — https://www.w3.org/TR/prov-dm/
2. in-toto attestation framework: signed statements about software artifacts — https://github.com/in-toto/attestation
3. SLSA v1.0 provenance specification — https://slsa.dev/spec/v1.0/provenance
4. OpenTelemetry tracing specification — https://opentelemetry.io/docs/specs/otel/trace/api/
5. OpenLineage object model — https://openlineage.io/docs/spec/object-model
6. Cloudflare D1 pricing — rows written, rows read, storage — https://developers.cloudflare.com/d1/platform/pricing/
7. GPT-5.6 on the declared universe
8. Kimi, given the same question and none of the first answer
9. GPT-5.6 refuses the self-report
10. Kimi on how few shapes there are
11. The strongest objection on the page


---

# Protocol Widgets: Self-Explanation, Vault Cards, and Native Embeds

slug: protocol-widgets · https://miscsubjects.com/a/protocol-widgets · tags: system, protocol, widgets · updated 2026-07-17T02:41:02.828Z

## What this article is

Protocol Widgets document the rendering system on miscsubjects.com.  
It explains how evidence appears as self-contained cards and embeds.  
The audience is operators who maintain the site, models that consume the API, and readers who view articles.

## Who claims what

Widgets are self-explaining.  
Every attachSelf() response returns _self.what, _self.how_to_use, and _self.related URLs.  
explainGrowStep() returns human-readable why/how text for each grow-queue step.  
Platform logos and rail styling live in widgets/platform_logos.js and widgets/social.js.

## What is known

FEATURES in self_explain.js is the canonical feature index.  
sourceToWidget() maps ledger sources to native cards for reddit, x, pubmed, youtube, and imessage.  
buildInlineEmbedMap() turns [[embed:slug]] markers into horizontal native cards.  
normalizeWidget() unifies directory rows, tasks, events, and claims into vault-card rails with shortHash ids.  
meta.widgets[] supports imessage, quote, stat, note, and gallery types as JSON series.  
Graph canvas widgets come from GET /api/graph with nodes as claims or sources and edges as supported_by, posted_by, challenges, or embeds.  
Widget rendering is deterministic from ledger JSON.  
Third-party oEmbed iframes are avoided for Reddit and X.

## What we do not know

Not all admin pages yet consume _self blocks.  
Widget accessibility with ARIA on rails remains partial.

## Limitations

Widgets display evidence only.  
They do not score or elevate claims.  
Weighting stays in claim.weight from /score.

## Disclaimer

This is not medical advice.  
Social anecdote widgets are anecdotal tier by definition.


---

# The Logic of the Logic: Recursive Ledger, Entropy, and Combinatorial Control

slug: protocol-logic · https://miscsubjects.com/a/protocol-logic · tags: system, protocol, logic, matrix · updated 2026-07-17T02:41:02.531Z

## What this article is

This document records the internal logic that builds and maintains the miscsubjects.com corpus.

It treats every article as a cell in a combinatorial matrix.

The ledger tracks entropy, coverage gaps, and cross-article mappings rather than medical outcomes.

## Who claims what

System-tier rules classify articles into peptide_root, condition, or stack using the PEPTIDE_CATALOG of 33 roots.

The combinatorial matrix places degenerative conditions and degenerative pharma on the same ledger plane.

delta = regen_score − degen_score serves as the elevation signal for queueing cross articles.

planNextTick() merges gap audit and entropy audit into a single prioritized slug list.

graph_grow_queue prepends matrix-planned slugs before legacy PRIORITY_SLUGS.

entropy_score rises with orphan count, missing roots, and low-delta written crosses.

parseCrossSlug() resolves article slugs to peptide×target cells for mapping backfill.

The pipeline table holds 1254 combo rows after full sync; deterministic seed replaces LLM-only pipelineSeed.

Reflex pass posts system-tier claims that cite live endpoint probes.

Rest gate (P8) logs energy_spent when a model pass is non-material.

Hash chains on sources, provenance, and contributions make post-hoc tampering detectable via verify endpoints.

## What is known

Article ontology, entropy scoring, and queue logic run on deterministic functions rather than editorial preference.

Full autonomous cron for P0–P8 phases is not continuously running; grow batch is the practical scheduler today.

LLM-driven pipelineMap weights are superseded by deterministic computeMapping for new syncs; historical rows may differ.

## What we do not know

The exact future coverage delta after the next full matrix tick.

Whether all 1254 combo rows remain current after the next deterministic seed update.

## Limitations

Meta-logic articles use system tier. They do not compete with human clinical claims on weight.

## Disclaimer

Recursive control optimizes corpus shape, not patient outcomes.


---

# What This Framework Enables: Use Cases Beyond Peptide Catalogues

slug: protocol-framework-utility · https://miscsubjects.com/a/protocol-framework-utility · tags: system, protocol, applications · updated 2026-07-17T02:41:02.243Z

## What this article is

This document explains what the miscsubjects.com protocol framework can do beyond peptide catalogues. It describes the build itself.

The framework separates transport (REST protocol), evidence atoms (claims), and presentation (widgets). Each layer remains inspectable independently.

## Who claims what

Tasks REST and dispatch directory let cron jobs and human operators invoke protocol steps as named functions.

Library-snapshot and poll endpoints support periodic external source refresh against existing claims.

## What is known

POST /api/protocol/ask returns gaps[] and ingest_hint. The ledger tells the user what evidence would materially improve the answer.

Combinatorial matrix generalizes to any inventory × target grid where regen/degen scores can be defined transparently.

Multi-model collaborate preserves each model's original contribution. This supports audit, dispute resolution, and bias detection.

Graph canvas GET /api/graph enables cross-article reasoning without copying full bodies into prompt context.

iMessage/WhatsApp ingest paths let lay users add anecdotal tier evidence that enters the same hash-chained ledger.

Obsidian vault export supports offline research workflows while keeping slug parity with the live corpus.

## What is unknown

Domain packs beyond peptides require new canonical catalogs. The engine (matrix, grow, claims) is domain-agnostic.

Federation across multiple miscsubjects instances is not implemented. Single D1 spine today.

Commercial RUO peptide commerce integration is out of scope. The framework is evidence organization only.

## Limitations

Accessible register articles still depend on claim tier discipline. Prose alone does not elevate evidence.

Usefulness scales with source forest density. Empty articles benefit from populate before ask.

## Disclaimer

Framework users remain responsible for their own research and medical decisions.


---

# Protocol API Structure: REST Surface, Objects, and Phase Machine

slug: protocol-api-structure · https://miscsubjects.com/a/protocol-api-structure · tags: system, protocol, api · updated 2026-07-17T02:41:01.604Z

## What this article is

This document describes the live REST surface and phase machine for miscsubjects.com.  
It is system documentation, not a compound catalogue entry.

## Who claims what

The build itself defines the contract.  
GET /api/protocol returns the authoritative machine map.  
API_QUICKMAP.md and PROTOCOL_SPEC.md are static mirrors of that contract.

## What is known

GET /api/protocol exposes the endpoint list, body schemas, and phase definitions.  
Two planes exist: /api/articles for CRUD and sub-resources, and /api/protocol for phase operations.  

Claims live in article.meta.claims[]. Sources live in meta.sources[] with prev/hash chain. All writes are append-only.  

POST /api/protocol/draft validates tiers, optionally verifies source URLs, and hash-chains sources.  
POST /api/protocol/populate ingests sources into an article without rewriting the body.  
POST /api/protocol/collaborate lets Kimi or Gemini append 1–3 claims.  
POST /api/protocol/score recomputes claim.weight and applies status:cut when below threshold.  
GET /api/protocol/next?role=writer hands out one open task atomically.  
POST /api/protocol/run executes one scheduler tick inside the 100-second request limit.  
GET /api/matrix/gaps lists missing roots and cross cells. POST /api/matrix/seed fills from the canonical catalog.  
Webhook POST /api/articles/{slug}/webhook accepts atomic appends of kind:claim|source|widget.

## What we do not know

Not every phase listed in PROTOCOL_SPEC.md has a deployed cron worker.  
Some phases still require manual POST /api/protocol/grow or dispatch tools.  
Rate limits and per-tenant quotas on gateway model calls are environment-dependent and not shown in the public contract.

## Limitations

Protocol slugs are immutable. Hard DELETE is blocked. Corrections use PATCH status:retracted or new revisions.  
Every phase transition must finish inside Cloudflare’s ~100-second cap. Batch work uses grow batch or cron ticks.

## Disclaimer

This API map is a research-ledger transport layer only. It grants no medical authority.

