EconomyFindings
The Hosted Profile
The multi-tenant cognition market deployment: a PostgreSQL store, an authenticated edge, isolated workers, and the ceilings each one enforces.
The cognition market ships in two deployments. The single-operator profile runs one venue on SQLite inside the trust-control plane, in one process. The hosted profile runs several tenants against one PostgreSQL database under forced row-level security, behind an authenticated HTTP edge, with job execution on separate Linux KVM hosts. Those tenants share the database, the edge replicas, and the worker hosts; row-level security and per-tenant ceilings are what hold them apart.
The two deployments answer a liveness question differently, and that difference decides where a status-gated purchase can happen. The single-operator venue holds the status feed's sparse map, so it can produce the portable non-inclusion proof such a purchase presents. The hosted journal retains a status epoch only as a signed sparse-map root and keeps no per-finding sparse proof, so once a tenant has any status epoch, catalog_non_live_finding_ids answers with every finding id it was asked about: a single read returns not_found and a catalog page comes back with those rows removed. The hosted edge carries no bid, ask, or reveal route either: purchase records, purchase results, and purchase terminals are coordinator-produced and have no public ingress here.
Supported topology
Four crates carry the hosted profile, and four binaries run it. The edge and the store link into one server process; the worker library links into a daemon that runs on hosts of its own.
| Part | Crate | Where it runs |
|---|---|---|
| PostgreSQL journal, tenancy, storage authority, retention | crates/platform/chio-finding-market-store-postgres | Linked into every process that opens the database, each under its own least-privilege role |
| HTTP routing, credential authentication, request admission, load shedding | crates/platform/chio-finding-hosted-edge | Linked into the market server, listening on loopback behind a TLS proxy sidecar in the same pod |
| Firecracker-isolated execution and the guest frame protocol | crates/platform/chio-finding-worker | Linked into the worker daemon on a dedicated Linux KVM host |
| Worker daemon: preflight, tenant rotation, tick reporting | crates/products/chio-finding-worker | Under systemd on the KVM host. SQLite is neither mounted nor admitted in either production role |
Two crates, one name
chio-finding-worker and lives at crates/platform/chio-finding-worker. The products crate is packaged as chio-finding-worker-daemon, sits at crates/products/chio-finding-worker, and ships a binary also named chio-finding-worker. The library is the one a profile validates against; the binary is the one systemd starts.The binaries divide by credential. chio-finding-market-migrate, from crates/products/chio-finding-market-migrator, owns schema changes under a migration-only role and runs as its own Job; runtime pods never receive that credential. chio-finding-market-server serves the authenticated loopback API from stateless replicas. chio-finding-worker executes jobs under fenced leases in Firecracker isolation. chio-finding-market-canary qualifies a deployment against an exact release candidate from an attested ephemeral runner. The container, systemd, and Kubernetes contracts live under deploy/cognition-market/.
What the edge serves
The router carries three health routes outside the concurrency limiter and five guarded routes inside it. Liveness and readiness stay outside because the proxy probes them on this same pod, and shedding a probe would restart a live sidecar exactly while the edge is saturated.
| Route | What it answers |
|---|---|
GET /health/live, GET /health/ready | Liveness, and a readiness answer that reaches the backend at most once per READINESS_ANSWER_LIFETIME |
GET /health/metrics | chio_finding_market_edge_requests_total in Prometheus exposition format, labelled accepted, denied, and shed |
GET /v1/release | The deployment id, candidate commit, artifact digest, and configuration revision the process is bound to |
GET /v1/findings, GET /v1/findings/{finding_id} | One bounded page, or one finding, for the buyer role. Each row is re-verified against its own signature and digest, and expired, voluntarily retracted, and enforcement-retracted findings drop out |
POST /v1/findings/publish | One signed chio.finding.v1 artifact from the seller role |
POST /v1/findings/events/{operation} | Exactly six operations: listing, delivery, challenge, verified-fix, retraction, and penalty |
Each operation fixes its own domain event kind, artifact schema, governed action name, and writing role, and anything outside that list resolves to no operation at all. Coordinator-produced records, which include admission, purchase, purchase terminals, adjudication, enforcement, settlement, status, and audit, have no public route. The challenge route accepts only the buyer_submission authorization branch, so a venue audit cannot enter through it, and a penalty write must be signed by the profile's pinned penalty authority and name itself in both issuedBy and governingOperatorId.
A tenant is chosen by the Chio-Tenant-ID header, and a caller authenticates with either a capability token plus a Chio-DPoP proof or an API key pair, whichever the tenant's policy admits. Every failure returns the same body: chio.finding.hosted-error.v1 with a stable code, a fixed message, the caller's request id, and a retryable flag that is true only for rate_limited, authentication_capacity_unavailable, request_capacity_unavailable, and authentication_dependency_unavailable. A request id that is empty, over its byte bound, padded, or carrying a control character is replaced by invalid-request-id rather than echoed.
Tenancy and isolation
Every tenant-scoped operation opens a transaction and runs SELECT set_config('chio.tenant_id', $1, TRUE) before it touches a row, so the binding is transaction-local and cannot leak into a pooled connection's next user. Catalog reads take the same setting under SET TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY, so a page is answered from one snapshot. Either way an unknown tenant returns TenantNotFound and a tenant the operator disabled returns TenantDisabled, which keeps durable state intact while every subsequent scoped operation fails closed.
Row-level security is what enforces the binding. Every table in TENANT_SCOPED_TABLES carries ENABLE ROW LEVEL SECURITY and FORCE ROW LEVEL SECURITY, so the policy binds the table owner as well, plus one permissive policy for all commands, applying to PUBLIC, whose USING and WITH CHECK expressions are both exactly (tenant_id = NULLIF(current_setting('chio.tenant_id'::text, true), ''::text)). The startup audit rereads all of that from the catalog and adds one condition the schema alone cannot state: the runtime role must not own any of those tables.
A statement that runs without the setting finds that predicate evaluating to NULL for every row, so it reads nothing and writes nothing rather than erroring. The security-definer functions refuse louder: each compares its requested tenant against the session setting before anything else and raises 42501 with a message naming the mismatch, such as tenant context does not match authority transition.
The store audits its own credential before it serves anything. verify_runtime_role refuses a role that is a superuser or carries BYPASSRLS, CREATEROLE, CREATEDB, REPLICATION, INHERIT, or any role membership, then checks its database privileges, its per-table privileges, its function grants, and the RLS surface table by table. Any drift returns HostedMarketStoreError::Configuration and the process does not start. The migrator, worker, retention, and replicator credentials each get their own audit, and the migrator is the only one permitted to bypass row-level security or create schema objects. Every pool connects with PgSslMode::VerifyFull, applied over whatever the DSN asked for, against the certificate authority the profile names.
Privilege separation extends inside the schema. The monthly spend accumulator is maintained only by a security-definer trigger on the reservation table, and the runtime role holds SELECT on it and no write privilege at all, so a compromised runtime cannot forge a low total for its own tenant and pass the ceiling that trigger enforces.
Storage authority
Each tenant carries one row of authority state: which store is authoritative, an epoch, a mode, a mutations flag, the last replication and outbox sequences, and the digest of the transition that produced the row. A new tenant is initialized by trigger at authority sqlite, epoch 1, mode shadow, with mutations enabled. The constraint chio_finding_market_authority_state_consistency_v1 keeps the authority and the mode consistent: sqlite pairs only with shadow or frozen, and postgres only with rollback_window, authoritative, retired, or frozen.
| Mode | What it permits |
|---|---|
shadow | SQLite holds authority. PostgreSQL accepts signed replication events from it and appends signed replication checks; it admits no domain write of its own |
frozen | The barrier state, reachable under either authority. mutations_enabled is false, replication events still land while SQLite holds authority, and it is the only mode cutover and rollback accept |
rollback_window | PostgreSQL holds authority and admits domain writes, while a stored deadline still allows a return to SQLite |
authoritative | Admitted by the domain-write guard alongside rollback_window and retired, and accepted by freeze as a source mode. No transition sets it |
retired | PostgreSQL holds authority, admits domain writes, and the rollback deadline has passed |
A domain write reaches durable state only when the tenant's authority is postgres, mutations_enabled is true, and the mode is one of rollback_window, authoritative, or retired. The guard runs inside the append function under a row lock, so a freeze that lands mid-flight refuses the write rather than racing it.
A transition is one signed chio.finding.hosted-authority-transition.v1 envelope applied under a tenant advisory lock, and each one raises the authority epoch by exactly one, which both a table constraint and the function require. Presenting the identical envelope twice returns the replay outcome instead of moving the epoch again; anything that fails a precondition returns a rejection and leaves the row untouched. Each applied transition is inserted into chio_finding_market_authority_transitions, where a trigger rejects any later UPDATE or DELETE, so the authority history is append-only. The replication credential that applies these barriers is separate from the runtime credential and cannot invoke public market commands.
Capacity ceilings
Every ceiling below is an enforced constant or a setting the profile validates before the process starts. The ones that refuse work fail closed, and none of them degrades a guarantee to keep going. The admission, spend, and job ceilings are per tenant; the request ceilings bound one edge replica.
| What it bounds | Value | Constant or setting | When it binds |
|---|---|---|---|
| Unexpired proof nonces one tenant may hold at once | 1_000..=10_000_000 | identity.nonceCapacity | A sweep runs first; if the count still stands, the admission returns Capacity and the caller reads authentication_capacity_unavailable, HTTP 503, retryable |
| Retained request admissions per live-proof slot | 64 | RETAINED_BINDINGS_PER_NONCE_SLOT | The same capacity refusal. A recorded admission is never evicted to make room, because evicting one would break the retry it exists to serve |
| Interval after which an admission sweeps expired proof state | 3_600 seconds | DPOP_SWEEP_INTERVAL_SECS | No refusal. The sweep runs inside the admitting transaction, and capacity pressure triggers it early |
| Monthly spend units per tenant | 1..=MAX_I_JSON_INTEGER | HostedTenantLimits | The accumulator trigger raises chio_finding_market_spend_period_ceiling_v1 inside the inserting statement, which the store maps to Capacity |
| Concurrent jobs per tenant | 1..=1_024 | HostedTenantLimits | No refusal. It caps the batch one worker tick claims for that tenant, together with the tick's job budget and the host-wide instance count |
| Queued jobs per tenant, counting pending, leased, and failed | 1..=database.maxJobsPerTenant | HostedTenantLimits | Job creation returns Capacity. A profile whose tenant value exceeds the global one refuses to start rather than being clamped |
| Retained jobs per tenant, counting every state | 1..=10_000_000 | database.maxJobsPerTenant, bounded by MAX_TENANT_JOBS | Job creation returns Capacity, checked under a tenant advisory lock so the count and the insert cannot interleave |
| Rows in one catalog page, and finding ids in one liveness query | 100, defaulting to 50 | MAX_CATALOG_PAGE | A larger limit returns Invalid("catalog limit"), which the caller reads as invalid_request, HTTP 400 |
| In-flight requests per edge replica | 1_024 | MAX_CONCURRENT_REQUESTS | The request sheds before a handler runs, carrying request_capacity_unavailable, HTTP 503, retryable, and its own request id |
| Request body | 4 MiB | MAX_HTTP_BODY_BYTES | The router's body-limit layer stops the request before a handler sees it, and the handler's canonical-body check refuses the same bound again |
| How long one readiness answer is reused | 1 second | READINESS_ANSWER_LIFETIME | No refusal. One backend check runs at a time, and a probe arriving while the answer has aged out and a check is already in flight reports not ready |
Live-proof capacity is one operator sizing decision applied to every tenant's admissions, with no per-tenant override, and both the profile and the authenticator refuse a value below 1_000, so the store's wider acceptance is unreachable through configuration. The shed count sits beside the accepted and denied counts on /health/metrics, which is absent from the Service and whose network policy admits only namespaces labelled chio.world/market-metrics-scraper, so traffic volume reaches a scraper without becoming publicly routable.
The other profile's ceilings explain when an operator reaches for this one. A single-operator venue serves discovery from a companion pool bounded by MAX_READ_COMPANIONS, and its serving-owner lease makes exactly one process the writer. A deployment that needs more concurrent writers wants the PostgreSQL profile, not a larger bound there.
The worker
A job is a row in chio_finding_market_jobs holding a canonical JSON payload, its digest, and a job_kind. That kind is an operator-chosen identifier bounded by MAX_JOB_KIND_BYTES, not a closed vocabulary: what constrains it is the signed worker capability, which must name the same job_kind as the job it authorizes. The state column is closed, at pending, leased, completed, failed, and exhausted, with table constraints tying the lease columns, the result columns, and the error code to it.
One tick claims a bounded batch for one tenant under a fenced lease, renews that lease on a heartbeat while the guest runs, and sorts each job into one of five outcomes: Completed, GuestRejected, Retried, Exhausted, or Cancelled. A guest that returns a result whose exit classification is not Succeeded still completes the job durably; the attested result records the refusal.
A failed execution takes one of two paths. If the job has already used its attempt budget, the worker calls exhaust_job with the error code and the job stops there. Otherwise it calls fail_job with the same code and a delay of retry_base_secs * 2^(attempt_count - 1), with the exponent capped at 10 and the delay capped at 3,600 seconds, and the row returns to failed to be claimed again when it comes due.
The budget itself is the smaller of the worker profile's maxAttempts and the attempt limit inside the signed job capability, so a profile cannot grant more attempts than the capability authorized, and a capability whose attempt limit fails to verify exhausts the job at once rather than retrying it. Shutdown is the third path: a canceled execution relinquishes its lease so another worker can claim the job immediately, and a lease already lost to expiry leaves the row where the next claim finds it.
Isolation is part of the contract rather than the deployment's discretion. The worker stages digest-pinned guest assets into a unique jail, starts Firecracker only through its jailer, and exchanges bounded canonical JSON frames over virtio-vsock; the guest supervisor owns the vsock endpoint and runs the untrusted workload in a cgroup with a hard file-descriptor limit. Profile validation refuses unless requireDefaultSeccomp is true and networkEnabled is false, and it refuses a lease duration that does not outlive the execution timeout, so a lease cannot expire under a running guest.
Operator commands
Two subcommands of chio finding operator act on a hosted deployment. Both read a strict canonical private JSON profile and both refuse before touching a listener, a pool, a rail, or a remote signer.
chio finding operator validate-hosted --profile /etc/chio/hosted.json
chio finding operator evaluate-canary \
--profile /etc/chio/hosted.json \
--observation /run/chio/canary-observation.jsonvalidate-hosted closes the deployment boundary offline. It requires the file to be a private regular file inside its byte bound and byte-identical to its own canonical form, validates the profile, then opens every referenced path, resolves every named secret environment variable, builds the authenticator, loads the API-key pepper, loads TLS, loads the trusted proxy, loads a signer for every role in FindingHostedSigningRole::ALL, loads the bond observer and the impairment publisher, and on Linux builds the worker executor. A run that survives all of that prints hosted_profile: valid with the deployment id, endpoint, tenant count, and signer count, or the same facts as a chio.finding.hosted-profile-validation.v1 report under --json.
evaluate-canary judges one audit-authority-signed observation against the same profile and prints canary_decision: promote or canary_decision: rollback with one reason: binding, observation_window, freshness, availability, error_rate, latency, queue_age, or security_invariant. A rollback decision exits non-zero, so a promotion script can branch on the exit code alone.
Where the runtime refuses instead
See also
- The Cognition Market for the finding record, the six market flows, and the crates behind them. That page describes each flow as the single-operator deployment runs it.
- Finding Status for the signed status epochs and the portable non-inclusion proof a status-gated purchase presents, which the single-operator store retains and this one does not.
- Paid Reveal for the reversible hold, the digest gate, and the terminal states of the purchase chain that runs outside this deployment.