HIPsHanzo Proposals
Back to HIPs
HIP-1000FinalStandards TrackApplication

Author — A Royalty Bound to a Repository

Hanzo AI
Created: 2026-08-20
Requires: HIP-0139

HIP-1000: Author — A Royalty Bound to a Repository

Abstract

/v1/author is a royalty program: an author proves control of a repository, and every org that deploys a project built from that repository generates a royalty against its own metered spend. It is implemented in hanzoai/cloud at apps/author. This HIP states the contract the program must hold to — how attribution is proven, how a royalty amount comes to be, and the line between recording money and moving it.

Motivation

Open-source work already runs on the platform and already generates spend. There was no edge connecting the two, so the spend had no author and the author had no claim. apps/author supplies that edge; this HIP supplies the rules it must not break, because every one of them is about somebody else's money.

Specification

The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as in RFC 2119.

Attribution proves control of code, not identity of a person

A repository earns only after a verification that demonstrates control over it: either a forge token showing admin or push permission, or a file on the default branch carrying the author's minted verify code (apps/author/authors.go:20-23). Both prove the same fact — that the claimant can change what that repository deploys. Neither is a claim about who the claimant is, and the program MUST NOT treat it as one.

A deploy edge is recorded per (repo, project, deploying org) and is idempotent (apps/author/authors.go:24-26). Without that edge nothing accrues, so an unattributable deploy earns nothing rather than earning by default.

The royalty is a latch, not a computation over history

Accrual is at most once per (author, deploying org, period). The amount is that org's metered spend for the period times the share stored on the author at that moment: earningCents = spendCents * shareBps / 10000 (apps/author/basis.go:48), evaluated in accrueOne (apps/author/authors.go:336).

The row written by the latch captures share_bps, spend_cents and earning_cents in the same transaction as the balance increment. That row is a value, and it MUST be served verbatim and never recomputed (apps/author/basis.go:15-30). A later rate change, a share renegotiation or a restated spend figure therefore cannot rewrite what an author was already told they earned.

The current rate card is a model, not a value, and MUST be served separately and labelled with its asOf. Stamping a card onto a historical row would be a fabrication by construction: one row's spend can span several cards' pricing windows, and some of its components were never priced by a card at all.

An author's own org is excluded from the fold (apps/author/authors.go:311-313), so the program cannot pay a royalty on self-dealing.

A per-org spend read that fails is skipped and picked up on the next sweep (apps/author/authors.go:320-323). A partial answer that is correct beats a whole answer that is wrong.

Accrual records what is owed; payout records a disbursement; neither moves money

accrued only rises. paid rises only when a payout is recorded, and a payout MUST NOT exceed pending = accrued − paid, reserved atomically before anything else happens (apps/author/store.go:1058-1064, refusal text at apps/author/typed.go:113-117). A recorded payout that the treasury cannot back is voided rather than left standing (apps/author/store.go:1100).

No route in this capability settles money. A human does that out of band. The program is a ledger of obligation.

Identity is never an input

The earning org is read from the validated principal, never from a request field. The platform-wide operations are admitted only by a SuperAdmin bit that the identity boundary mints and that the ordinary principal does not carry (apps/author/typed.go:84).

The support view of an author's basis MUST be produced by the same builder as the author's own read (apps/author/typed.go:845), so support and author can never be looking at two numbers.

Store, price, events, telemetry, stage, upstream

The capability owns one encrypted SQLite database, author, opened through the one opener (sqlpool.Open("authors", dir), apps/author/store.go:177). It is free, in those words: Price: cloud.Free (plugin/author/main.go:21) — it records obligations and meters nothing. It publishes no events on the bus, so a customer's webhooks receive nothing from it; money actions land best-effort records on cloud's audit trail (apps/author/authors.go:133, :475-479). Beyond that and the request span it emits log lines only. Its stage is beta — the manifest row declares it (manifest/apps.go:388, Stage: Beta; HIP-0139 §8). It derives from no forked, embedded or mirrored OSS project.

What this refuses

  • No disbursement. There is no address here that moves money, and adding one would put a mint authority behind an accrual sweep.
  • No recomputation. There is no address that re-derives a historical row.
  • No per-row rate card. The card is current or it is absent.
  • No 404 on "not enrolled". A caller who has never enrolled gets an honest short answer, because 404 on that address answers "is this org an author" to anyone who asks (apps/author/typed.go:208-210).

Rationale

The obvious alternative is to compute the royalty on read: keep no ledger, and derive the number from current spend and the current share whenever someone looks. It costs auditability. The author's dashboard number would change when a rate changed, without anything having happened, and no one could reconstruct what they had been told last month. The latch buys immutability for the price of one row.

The second alternative is to settle automatically at sweep time. That braids a disbursement authority into a scheduled job, which is the shape where a single arithmetic defect becomes a fleet-wide payout. Splitting accrue from pay means the worst outcome of a defect in the sweep is a wrong number on a screen.

Security Considerations

Verification is the only thing standing between an arbitrary caller and another project's earnings. The file method proves default-branch control, which is the right property — someone who can change the default branch can already change what deploys — but it does mean a repository whose default branch is writable by many is claimable by any of them.

The share and status operations sit behind the SuperAdmin bit. That bit is a header only the identity boundary can mint; any deployment that lets a client set it directly hands over the ability to approve authors and record payouts.

The payout ceiling is the one arithmetic guard that stands between a recorded obligation and an over-payment, and it is enforced by reservation rather than by a read-then-write, because a read-then-write races.

References

  • HIP-0135 — What Is Public

Copyright

Released under CC0 1.0 Universal Public Domain Dedication.