event: the published contract says what the door does
CI/CD / image (push) Successful in 23m20s
CI/CD / gate (push) Successful in 1m16s
CI/CD / containment (push) Successful in 2m39s
Hanzo CI/CD / cicd (push) Successful in 1m16s
CI/CD / rollout (push) Failing after 7s
CI/CD / reach (push) Skipped
CI/CD / fanout (push) Skipped
CI/CD / receipt (push) Failing after 2s
CI/CD / image (push) Successful in 23m20s
CI/CD / gate (push) Successful in 1m16s
CI/CD / containment (push) Successful in 2m39s
Hanzo CI/CD / cicd (push) Successful in 1m16s
CI/CD / rollout (push) Failing after 7s
CI/CD / reach (push) Skipped
CI/CD / fanout (push) Skipped
CI/CD / receipt (push) Failing after 2s
The door description still promised "NO CREDENTIAL IS ALSO ADMITTED ... filed under the reserved $public tenant" — and it goes into the OpenAPI document customers read. The code has refused since the key work landed: 401 ingest_key_required with nothing presented, 403 ingest_key_unknown for a credential that names no project. A contract that promises the opposite of the code is worse than no contract, because a client writes against it. The projection survives for the reduced principal it was narrowed for — a workspace token writing into its own org. Co-authored-by: Hanzo Dev <dev@hanzo.ai>
This commit is contained in:
+18
-21
@@ -852,30 +852,27 @@ var doors = []door{
|
||||
"back always takes a real bearer. A Hanzo Team workspace token resolves its org at " +
|
||||
"REDUCED capability: the signed " +
|
||||
"account names the person, so a `distinctId` in the body cannot pin events on a colleague.\n\n" +
|
||||
"NO CREDENTIAL IS ALSO ADMITTED, and that is the point — a logged-out visitor has none. " +
|
||||
"Such a write is PROJECTED: filed under the reserved `$public` tenant, narrowed to what the " +
|
||||
"SERVER can name — pageviews and errors, plus the closed autocapture vocabulary ($click, " +
|
||||
"$input, $change, $submit, $view) — where EVERY one of those names is resolved through a " +
|
||||
"server-owned table and stored as that table's value, so the name on the wire is never the " +
|
||||
"name in the row. Stripped, too, to the fields the projection names, so revenue, personId, " +
|
||||
"groupId and every property but the element annotation " +
|
||||
"cannot reach a row — and an exception is carried only on an error, never on an " +
|
||||
"interaction, so a click cannot ship a stack trace into a row's attributes. " +
|
||||
"ITS IDENTITY IS NAMESPACED for the same reason the name is: nobody signed for it, so a " +
|
||||
"`distinctId` off the wire is stored under a reserved `$anon:` prefix that no identified " +
|
||||
"subject carries — an anonymous visitor still counts as one visitor, and still cannot be " +
|
||||
"joined to a person the org knows. Everything refused is counted in `dropped`. On a " +
|
||||
"published-site host " +
|
||||
"the same projection applies with that site's org as the tenant. But a credential that IS " +
|
||||
"presented and does NOT resolve is 403, never quietly downgraded: filing a misconfigured " +
|
||||
"key's events under $public would hide them in a partition their owner cannot read.\n\n" +
|
||||
"The anonymous lane alone is bounded: 413 over 64 KiB, 400 over 50 events, 429 on the " +
|
||||
"NO CREDENTIAL IS REFUSED: a write the server cannot attribute to a project is 401 " +
|
||||
"`ingest_key_required`, and a credential that IS presented but resolves to no project is " +
|
||||
"403 `ingest_key_unknown`. Nothing is filed under a shared tenant — events nobody can " +
|
||||
"read are worse than events nobody sent, because the caller is told it succeeded. A " +
|
||||
"browser bundle therefore always ships a pk-, which is what /v1/event.js takes.\n\n" +
|
||||
"A REDUCED principal — a Hanzo Team workspace token — writes through the PROJECTION into " +
|
||||
"its own org: narrowed to what the SERVER can name (pageviews and errors, plus the closed " +
|
||||
"autocapture vocabulary $click, $input, $change, $submit, $view), where every one of those " +
|
||||
"names is resolved through a server-owned table and stored as that table's value, so the " +
|
||||
"name on the wire is never the name in the row. Stripped, too, to the fields the projection " +
|
||||
"names, so revenue, personId, groupId and every property but the element annotation cannot " +
|
||||
"reach a row — and an exception is carried only on an error, never on an interaction, so a " +
|
||||
"click cannot ship a stack trace into a row's attributes. It does NOT name the person: the " +
|
||||
"signed account is the identity, so a `distinctId` in the body cannot pin events on a " +
|
||||
"colleague. Everything refused is counted in `dropped`.\n\n" +
|
||||
"The projected lane alone is bounded: 413 over 64 KiB, 400 over 50 events, 429 on the " +
|
||||
"per-client-IP and per-peer caps, and a DNT:1 or Sec-GPC:1 request stores nothing and says " +
|
||||
"so in the receipt. Two stored values carry their own bounds on top, because a request cap " +
|
||||
"does not bound one value: an element annotation over 2 KiB (or a trail over 32 steps) and " +
|
||||
"an exception class over 256 bytes are dropped from the row, which still lands. Where a " +
|
||||
"deployment switches anonymous capture off, a credential-less " +
|
||||
"write is 403 instead. Authenticated bodies are offered to the observability plane first, " +
|
||||
"an exception class over 256 bytes are dropped from the row, which still lands. " +
|
||||
"Authenticated bodies are offered to the observability plane first, " +
|
||||
"which claims LLM-observability ingestion batches and declines everything else.",
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user