oc · me
§ changelog

What shipped. When.

Product-level changes. Spec changes live at docs.ochk.io. Incident post-mortems land here once they're written.

me.ochk scope trim · /me/agents + /me/family removed.

v2.2.12026-05-14
  • > /me/agents removed · oc-agent delegations are an OC Agent protocol surface, not a me.ochk surface. The user-facing manage-my-delegations UI belongs on agent.ochk.io (alongside compose, inspect, verify) once the @orangecheck/agent-core extraction lands. Hosting the full BIP-322 signing + envelope canonicalization + revocation flow inside /me was a protocol-vs-product responsibility leak, not a feature.
  • > /me/family removed · cross-family discovery cards are a marketing surface (and the cross-family scope-grant CTA was wired to a feature no sibling product consumes yet · per OCHK-V3-PLAN §10 phase-1 status). Cross-family scope-grant infrastructure (/api/family/scopes/<verb>, family: project_key prefix, /me/scope-grant family branch, /me/identity#grants family badge) stays · those are sibling-side endpoints, not user-facing pages.
  • > Removed: src/pages/me/agents.tsx, src/pages/me/family.tsx, src/pages/api/me/agent-delegations.ts, src/lib/me/agent-delegations-canonical.ts, src/lib/me/agent-delegations-store.ts and their tests. Wallet-persona nav drops the two entries between graduate and transactions.

cross-integrator sybil-resistance · signed activity attestation, end-to-end.

v2.2.02026-05-13
  • > Six selective-disclosure scopes for cross-integrator activity, each computed from the user's real signed envelope stream · cross_integrator_event_count (volume · A + agent), cross_integrator_human_event_count (volume · human only), cross_integrator_lifetime_sats (depth · cumulative user-earned sats), cross_integrator_distinct_count (breadth · distinct integrators), cross_integrator_oldest_event_at (duration · first activity timestamp), cross_integrator_active_days (habituality · distinct UTC days with at least one event). Integrators compose layered gates: "≥10k sats AND ≥3 distinct integrators AND oldest ≥90 days ago AND ≥30 active days" · sybils cannot speed-run that combination.
  • > Resolver derives all six values from a single listEventsForUser query · zero round-trip overhead when an integrator requests several activity scopes at once on the same event response. Per OCHK-V3-PLAN §6 phase-2 selective-disclosure posture · each value is a single number, no per-integrator detail, no timestamps. Granting one scope to one integrator does not grant it to any other.
  • > Signed activity attestation · GET /api/me/activity-attestation returns a content-addressed, ed25519-signed envelope wrapping all six values + computed_at + 24h expires_at. Same envelope key that signs every billable event, rebind, and trust attestation; same JWK rotation surface at /.well-known/oc-envelope-jwks.json. The "trivially to verify" property of the strategic claim is now cryptographic, not based on trusting OC's API response.
  • > Public client-side verifier · /verify-activity accepts a pasted attestation JSON, fetches the envelope JWKS DIRECTLY from me.ochk.io (no API round-trip), runs all five checks in the browser via @noble/curves: canonical-bytes decode, sha256 id match, JWK by kid, ed25519 signature, freshness. Each check renders ✓/✗ + detail; overall panel goes success-accent when every check passes. Zero OC-trust posture documented inline.
  • > User-facing surface · /me/transparency now hosts ActivityAttestationCard · fetches the user's own signed attestation, renders the six values with a fresh/expired badge, copy-button for the full JSON bundle. Forward to any verifier (integrator, auditor, forum gating on activity) for a one-function-call verdict.
  • > SDK helper · @orangecheck/me-client ships oc.identity.verifyActivityAttestation(bundle, options?) on both the main entry and /server. WebCrypto-backed Ed25519 verification; works on Node 20+, Vercel Edge, browsers. Returns typed ActivityVerifyResult { ok, reason, attestation, checks } · never throws. Auto-fetches + caches the me.ochk.io envelope JWKS for 1h with stale-on-error and single-flight dedup, mirroring the established oc.webhook.verify pattern.
  • > Trust attestation OTS pipeline · trust attestation envelopes now actually anchor to bitcoin. RecordedTrustAttestation gained the four anchor fields parallel to RecordedRebind (ots_calendar_url, ots_proof_b64, ots_submitted_at, relay_published). Sweeper at /api/cron/anchor walks trust:by_id alongside events / payments / rebinds. MeEnvelopeKind union extends to trust_attestation with d-tag prefix oc-me-trust. /verify/[id] TrustView renders the OtsPanel against real proof data once the cron sweeps. Audit divergence detector (/api/audit/divergences) walks trust rows for the ots_pipeline_lag tripwire so stalled cron surfaces within the day.
  • > Shared AnchorBadge component · /verify/[id], /me/home, /me/wallet, /me/earn, /me/transactions, /me/developer, /me/identity (rebind history + trust attestations), /me/projects/[id]/events, /me/projects/[id]/trust, /me/projects/[id]/overview test-fire. Every envelope-rendering surface in the product now shows ⛓ anchored / ⏳ pending / ○ not anchored with consistent tone and tooltip. The previously-prominent border-left disclosure on /verify/[id] for unanchored envelopes (explaining the pending-vs-anchored state) is preserved.
  • > Marketing surface · /scale ships a SybilResistanceCompounding section · the strategic claim quoted in prose, the four orthogonal axes listed by scope code, the layered-gate verifier code, and a displacement callout naming the adjacent-category vendors (Auth0/Clerk, Sift/Stripe Radar, hCaptcha/Turnstile, Castle/Cloudflare) that this primitive subsumes when OC is the auth surface. Three CTAs at the bottom: /verify-activity, docs.ochk.io/me/sdk, /me/transparency.
  • > Self-service deletion-requests · DELETE /api/me/account/deletion-request lets a user cancel a queued / reviewing request without emailing security@ochk.io. /me/settings#advanced surfaces the user's active request inline (id + status_at + admin_note) with a "cancel this request" button; submit button disables when a request is open. /me/admin/deletion-requests distinguishes user-cancelled rows ("BY USER" muted badge) from admin-cancelled ones via admin_note pattern matching.
  • > /me/operator rejected-application dead-end fix · StatusLauncher progress no longer renders "0 / 5" for the off-path 'rejected' stage. LIFECYCLE_META.rejected gets a "re-apply below ↓" CTA + scroll-anchored OperatorApplyCard with a preamble. /me/wallet RecentSends refreshes immediately on successful send/withdraw via a tick state (was waiting up to 60s on the background poll). /me/identity sites tab sorts newest-first by first_session + renders a NEW badge on sites first seen within 7 days; alert_new_site notification deep-link upgraded from #sites to #site-<domain>.
  • > docs.ochk.io/me/sdk grew a `oc.identity.verifyActivityAttestation` section with the layered gating code, five-check breakdown, envelope-JWKS-vs-auth-JWKS distinction, and a callout to /verify-activity for third parties who can't or won't write the verifier themselves.
  • > 901 oc-me-web tests across 109 files (was 866 across 107 · +35 net). 90 @orangecheck/me-client tests (was 82 · +8 for the identity verifier). All envelope-store transitions and the new sybil-resistance scope resolutions covered.

operator infra · single-vendor + operator-key diversity model.

v2.1.02026-05-12
  • > Charter amendment · FEDERATION-DEPLOYMENT.md §1.3 reframed from "distinct hosting environment" (vendor diversity) to "distinct hardware-backed operator key, held by distinct legal entity, ideally distinct jurisdiction" (operator-key diversity). New §1A "Cryptographic-control model" pins the four operator-held items (Ed25519 identity, DKG share, charter sig, payout + exit sigs), the four-threat analysis table, and the conformance test (pubkey fingerprint distinctness + signed jurisdictional attestation).
  • > Code consolidation · /src/lib/hosting/ collapsed to Fly.io single-vendor. Hetzner adapter (248 LOC) + Vultr adapter (183 LOC) + cloud-init.ts (122 LOC) deleted. provisioner.ts refactored 529 → 200 LOC. Net -700 LOC of dormant code · the wizard UX had already de-facto collapsed to Fly-only region selection and the multi-vendor branch was costing maintenance for zero benefit.
  • > Stronger invariant · vendor diversity did NOT detect "same person runs all M seats on 3 vendors"; operator-key fingerprint collision DOES (automated check). Vendor diversity did NOT detect "same legal entity, different vendors"; the inviting-operator's signed jurisdictional attestation DOES. The cryptographic-control model addresses the threats vendor-diversity claimed to address, plus the threats it silently missed.
  • > Why this is safe · Fedimint threshold-signing already prevents any single vendor from moving funds, regardless of who hosts the daemons. Disaster-recovery to a different vendor is now a documented runbook step (operator restores from encrypted backup with their local key on any infra) instead of an architectural requirement · bypass parity in oc-guardian-kit/BYPASS.md covers cross-vendor moves.
  • > HostedHardwareCard region list flips to 15 Fly.io regions covering the same geographic footprint Hetzner + Vultr did. Admin /me/admin/hosted + vendor-health dashboard relabeled. Legacy hetzner/vultr historical rows preserved on hosted-store with a "legacy" bucket on vendor-health for incident-response context.
  • > Operator UX rebuild · /me/operator gets a new OperatorAtAGlance hub for operating-stage operators · top strip with operator-key fingerprint + federation count + aggregate charter-compliance · pending-signatures panel (honest about the kit v0.2 gate) · per-federation health rollup · recent alerts feed. The runbook + hosted-hardware + participation-fee + acceptance-verifier cards collapse into a "more tools" drawer for operating-stage operators (still expanded for accepted-no-federation / pending-review stages where they're part of onboarding).
  • > Per-federation slug page · lifecycle walker upgraded to active-step focus · the first not-done stage gets a primary-tinted highlight card with the step label + a concrete next-action (link or inline copy) so the operator never has to infer the workflow. Active-stage timeline dot pulses; done stages stay success-tinted. Seats-complete note now reads §1A diversity state inline: "4 distinct keys · §1A ✓" or "bootstrap shape · 1 distinct key (v1-launch pattern)" or "3 distinct of 4 · §1A not yet met". SeatRoster top-strip indicator + per-cell collision badge surface the same property.
  • > Charter validator · validateCharter() in lib/federations/charter-validator.ts now imports the seat-diversity helper so the same §1A math runs UI-side + server-side. Production-mode upserts with operator-key collisions are BLOCKED (issue, not warning); bootstrap-mode upserts get an honest warning. Messages reference §1A + §1.3 rather than the legacy §1.1 phrasing.
  • > Helper consolidation · fingerprint(pubkey) (12+6, terse · hub strip + seat cells) + fingerprintLong(pubkey) (16+8, inline-prose · /operators marketplace + /me/operator/incidents + AcceptanceVerifierCard). Single source of truth for operator-pubkey display across every surface · regression on the truncation surface surfaces everywhere.
  • > Severity filter pills on /me/operator/incidents matching the audit/notifications/events pattern · per-severity counts off the unfiltered list, tone-tinted active state (destructive/warning/info), pure incidents.filter() over the cached feed.
  • > 843 tests across 102 files (was 820 across 101 · +23 net for the new helpers + charter-validator §1A coverage + fingerprint shape coverage).

integrator security · notification substrate · persona-aware UX · workflow loops closed.

v2.0.02026-05-11
  • > HMAC request-signing · Stage 1 (advisory) + Stage 2 (enforcement). 256-bit signing secret per project · revealed/rotated Stripe-style on /me/projects/[id]/keys. Wire format: X-OC-Signature: t=<ts>,v1=<hex> over `${ts}.${rawBody}`. Per-project require_signed_events toggle flips advisory→enforce. Tamper checks: 5-minute timestamp window + constant-time MAC compare in lib/developer/event-signature. Enforced uniformly across every integrator write endpoint · /event, /event/batch, /trust-attestation · the toggle can't be bypassed by switching surfaces. Closes the "stolen project_key replay" gap.
  • > integrator quickstart restructured · honest 8-step path (was claimed-6/actually-7) with the HMAC hardening step (step 8) surfaced where integrators read code samples · the secret reveal, wire format, and start-in-advisory-then-enforce playbook in one read.
  • > notification substrate · per-user, kind-namespaced (project.frozen / unfrozen / rebound / rate_limited · webhook.dead_letter). /me/notifications full list with kind-filter pills + mark-read / mark-all-read. Top-of-page NotificationsBanner on every /me/* page surfaces unread items. Header bell with unread-count badge. /api/me/notifications GET + POST (id | mark_all). Click-through mark-read on every deep_link (keepalive fetch survives navigation). Hourly dedupe on rate-limit notifications via kv.incr TTL to avoid notification-feed flooding under sustained burst.
  • > admin actions emit notifications · /api/admin/projects/[id]/freeze (frozen + unfrozen variants) + rebind both record a project.frozen / unfrozen / rebound notification keyed to the project owner. Webhook dead-letter cron records webhook.dead_letter when retry budget exhausts. /api/integrator/event 429 fires project.rate_limited (deduped). Users learn their project state changed without needing to revisit /me/projects.
  • > operator self-serve publish-invite · POST /api/operator/federations/[slug]/publish-invite · creator-only authorization (creator !== session.did_oc → 404, not 403 to avoid pubkey enumeration). Operator runs DKG ceremony via oc-guardian-kit out-of-band, then pastes the resulting Fedimint invite + (optional) charter_hash here · this flips the federation overlay row to `live` and the next /me/wallet visit on any email-OTP user provisions a fedimint client against it. No code redeploy, no admin involvement. Closes the "create federation → bind on `live`" loop.
  • > persona-aware signup/signin · WelcomeIntentCard captures user vs integrator vs operator intent on first /me visit. Sidebar re-orders personas via lib/me/persona-order (active-path pinned to position 0 → declared-intent to position 1 → canonical otherwise; pure function with 14 vitest cases including stability + immutability). /signin redirects integrator → /me/developer · operator → /me/operator · user/null → /me. Return_to from query always wins (integrator flows expect to land back on integrator site).
  • > click-through mark-read · clicking "open →" on any notification deep_link (both /me/notifications and NotificationsBanner) fires the mark-read POST with keepalive=true so the browser ships it through navigation. No reload step · saves the user a roundtrip.
  • > events list class-filter pills · /me/projects/[id]/events surfaces A/B/C class pills with per-class counts when more than one class is present in the recent stream. Same UX as /me/admin/audit + /me/notifications · consistent filtering language across the product.
  • > project home polish · /me/projects list rows now show frozen + HMAC (enforced/advisory) + last-event timing badges so integrators see project posture at a glance without drilling in. SigningPolicyBadge on /me/projects/[id] credentials block links to the keys tab for the enforcement toggle.
  • > cross-user authorization hardening · projects-store HMAC helpers (ensureSigningSecret, rotateSigningSecret, setSigningPolicy) covered by 12 new tests · /api/me/notifications POST refuses to mark-read a notification owned by a different user (store-level guard). API-layer auth-gating sweep across 15 operator endpoints + 14 project subroutes (verify, escrow, signing-secret, rate, events, test-fire, webhooks dead-letter, …) · regressing the 401 gate on any of them now breaks CI.
  • > webhook dead-letter notification deep-link to /me/projects/[id]/webhooks · users land on the dead-letter inspection UI directly from the alert.
  • > Vue 3 + Svelte 5 snippet stacks · /me/projects/[id] now hands integrators copy-paste install / OC-session composable (Vue ref-based) or runes store (Svelte $state) / signin button for the two largest non-React frontend ecosystems. Same SDK, framework-agnostic popup helper, same /api/auth/me bearer-token hydration path.
  • > 780 tests across 100 files.

operator self-serve federations · observability stack · transparency surfaces.

v2.0.0-prep2026-05-08
  • > operator self-serve federation creation · /me/operator/federations/new · 4-step wizard creates a federation in the registry overlay, one operator can own N federations. bootstrap mode lets a single operator fill all 4 guardian seats with provider-diverse infrastructure (charter §1.1 surfaces a warning rather than blocks; v1 launch reality with a documented path to ≥4 distinct operators).
  • > one-click seat hosting · per-seat "provision" button on /me/operator/federations/[slug] creates a hosted-hardware request + provisions a Fly machine in seconds. 11 Fly regions + Hetzner + Vultr fallbacks. The kit-bridge JSON-RPC contract is frozen at GUARDIAN-KIT-BRIDGE.md so kit v0.2.0 implements against a stable surface.
  • > admin project rebind · /me/admin/projects · move a project from one federation to another with reason note + audit log; balance transfer is a federation-side operation run out-of-band.
  • > KV-backed federation registry overlay · /me/admin/federations · add federations at runtime without a code deploy (owner-gated). Charter validator gates writes; bootstrap-mode warns rather than blocks.
  • > per-federation charter generation · canonical bytes from federation row → sha256 → auto-published meta on creation + republished on every seat change. existing CharterSignButton works against self-serve feds without changes.
  • > OTS-anchored bond timestamps · OCHK-V2-PLAN §7 · sha256(address|bond_locked_at|bond_sats) submitted to OpenTimestamps calendar at upgrade time. /me/identity surfaces the proof status.
  • > cross-integrator activity score · OCHK-V2-PLAN §7 sybil signal · /me/identity activity score card; integrators that request the cross_integrator_event_count scope see one number, no per-integrator detail.
  • > participation-fee invoice generation · /me/admin/treasury · owner creates per-operator BOLT11 invoices, marks settled, settlement records inflow.participation_fee tagged with operator_id. operator-side statement at /me/operator/participation-fee.
  • > §6 production observability · structured JSON logger + access-log wrapper + /api/metrics Prometheus endpoint with per-route counters + duration histograms + per-event-subtype counters + webhook fan-out latency. p50/p95/p99 admin cards. public SLO banner on /status with auditable thresholds. /recovery DR runbook with RPO ≤ 15 min · RTO ≤ 60 min.
  • > public /economics dashboard · FEDERATION-ECONOMICS §10 · per-federation accruals + treasury balance + 30d trend + four-party-split walkthrough. CORS-open JSON at /api/public/economics-summary + /api/public/slo-summary.
  • > persona-switch flicker fix · 5 client hooks (useAdmin, useAdminBadgeCounts, useEarnings, useProjects, useBalance) module-cache their state across SPA navigations · admin nav + balance + projects no longer flash on every persona click.
  • > integrator-surface fixes · ProjectEvents now renders fetch errors instead of pinning to "loading…" forever; ProjectWebhooks same; ProjectShell module-caches the project across overview/events/billing/keys/webhooks pill clicks so the section nav no longer flashes.
  • > OCHK-V3-PLAN.md drafted (~600 lines) covering consensus-enforced four-way split · cross-federation BOLT12 mesh · multi-region within one federation · React Native mobile · passkey-bound scope grants + BIP-352 stealth Lightning · federation-threshold-signed bond attestations · OC Agent ↔ OC Me bridge · operator marketplace · transparency surfaces · cross-family Merkle anchoring. §12 documents honest scale ceilings layer-by-layer.
  • > §12 scale architecture phase-1 · /api/envelope/[id] now Cache-Control: max-age=31536000, immutable (anchored = immutable forever; verifier traffic stops hitting Upstash after first read). /api/dev-jwks bumped to 1d fresh + 30d SWR (kid is stable across deploys). Hot path /api/integrator/event parallelizes independent KV calls (project + escrow + grants + cap-check) and fire-and-forgets simulation/accrual writes; p99 ingestion drops from ~120ms → ~50-90ms.
  • > §12.6 cross-instance per-project rate limit · 1000 events/sec sustained per project_key, KV-backed atomic INCR + EXPIRE pipelined in one round-trip. A misbehaving integrator firing from many IPs across many Vercel lambdas now sees consistent 429s + Retry-After instead of saturating concurrency for everyone.
  • > §12.2 server half · /api/integrator/event/batch · up to 100 events per request, all under one project_key. Auth + project lookup + escrow read + scope grants + price-config-hash all amortize across the batch; recordEvent + idempotency writes parallelize via Promise.all. ~20-30× speedup for high-volume integrators (50-event batch in ~100-200ms vs ~3-4.5s sequential).
  • > §12.6 client half · @orangecheck/me-client v0.12.0 · MeClientError now surfaces retryAfterSeconds + errorCode + isRateLimited; new withRateLimitRetry(fn, opts) helper auto-honors Retry-After (capped at maxRetryAfterSeconds, default 30s) with exponential backoff fallback. Integrators wrap fireBatch calls and never write the sleep loop themselves.
  • > public /scale dashboard · honest layer-by-layer ceilings (Vercel, Upstash, single-fed Fedimint, LN gateway, Nostr, OTS) + current federation count → throughput math + the cross-instance per-project rate limit cap. CORS-open JSON at /api/public/scale-summary so third parties can fact-check the "federated, not infinite" framing in real time. /scale linked from footer + /trust due-diligence index.
  • > §12.6 phase-2 · weighted sliding-window rate limit · fixes the textbook 2× boundary issue on fixed-window. INCR current bucket atomic + GET previous in parallel; effective rate = current + prev × (1 - elapsed_ratio). Retry-After interpolates with elapsed-in-window. Pure O(1) computation; accuracy gain at 1000+ QPS.
  • > per-window event rate metrics · atomic per-minute buckets via kv.incr · 5min/1h sliding averages on /scale alongside lifetime totals. Prometheus scrapers see oc_me_events_per_sec{window="5m"|"1h"} as gauges, eliminating the lossy PromQL rate() over the legacy get-set lifetime counter.
  • > §11 graduation rate metric · the published north-star · /api/public/graduation-rate (CORS-open) reports lifetime + 30d + 90d count of federation→BIP-322 transitions plus per-month last-12 distribution. Surfaced as a prominent stat block on /economics#graduation, indexed from /trust. "Graduation IS the product thesis" verifiable by anyone replaying the rebind envelope chain.
  • > §9 per-user transparency · /me/transparency renders right-to-portability surface · summary cards over events / rebinds / scope grants / attest tier / projects, links to each live surface, single-button JSON export. Underlying /api/me/export extended to include rebinds + scope grants + attest tier alongside events + projects. Dedicated /integrate#scale section in the integrator quickstart shows the recommended high-volume pattern (withRateLimitRetry + fireBatch with idempotency_key per event).
  • > §9 charter compliance monitor · public /compliance dashboard walks every federation through the charter §1 property checks (oc_residual_bps cap, target_guardian_count, threshold shape, threshold ≤ guardians, distinct operator pubkeys, live-fed invite/seats/charter_hash/attestation freshness). Pass/fail per property + warnings vs blocking issues. CORS-open at /api/public/charter-compliance · same validator the admin UI runs. Linked from footer + /trust.
  • > webhook fan-out hardening · MAX_WEBHOOKS_PER_PROJECT=25 cap (with WebhookCapExceededError + 409 response) + bounded fan-out concurrency (10 in-flight workers per event, even with 25 endpoints). UI surfaces "X/25 registered" alongside the register button + warns when at cap. Closes a real production gap where unbounded webhook count × parallel fan-out could exhaust a Vercel function's outbound socket pool.
  • > §9 network-wide /transparency aggregate · single live dashboard rolling up every /api/public/* endpoint (scale, economics, graduation, compliance, slo). Distinct from /trust (link index) — /transparency is the live numbers in one page. Auditors land top-down without needing to know which sub-page hosts which signal.
  • > /me/transparency export now signed · the user-facing transparency JSON carries an Ed25519 signature + kid + body_hash_sha256 + jwks_url. Recipients (auditor/lawyer/journalist) verify provenance offline by recomputing sha256(body) → matching → fetching the JWKS → ed25519.verify. Same envelope-signing primitive every event/rebind/payment row already uses · per-user export gets the same provenance guarantee as the public envelope chain.
  • > /me/wallet rework for email-OTP users · led with the dead-end "federation custody · invite pending" panel before; now leads with the user's accrued earnings headline + BIP-322 graduation CTA ("sign in with a Bitcoin wallet → your earnings rebind to the new identity"). Federation custody status moved to a contextual disclosure inside the action card. Matching dead-end on /me empty-state EmptyState fixed too. Holistic UX audit doc shipped at OCHK-ME-UX-AUDIT.md with the deferred-fix queue.
  • > PersonaSwitcher preserves sub-path on switch · clicking a different persona chip from a deep sub-page used to dump users at the persona's bare home. Now the analog resolves: developer↔admin keep the projects sub-tree (incl. /[id]/billing/etc.), operator↔admin keep incidents + federations. Falls back to persona home when no analog exists. 5 vitest cases lock the routing math.
  • > /me/identity 4-tab pill-nav split · 910-LOC scrollable page → tier · sites · history · grants tabs with hash-sync. Header card with QR + address + badges stays always-visible above the tabs. Same pattern /me/settings already uses.
  • > /me/operator memberships now show live charter compliance per-federation badge (✓ compliant / ⚠ N warnings / ✗ N issues) sourced from /api/public/charter-compliance. Operators see their own federations' state without leaving /me/operator.
  • > §9 /federations/[slug] · public per-federation deep-view · core snapshot + charter §1 compliance + seats roster (with hosting source per-seat) + last-20 operator-signed incidents. CORS-open at /api/public/federations/[slug]. Wired from /compliance · network-rollup → individual fed in one click.
  • > §10 phase-1 · /me/family · cross-family discovery surface · seven sibling products (oc·attest, oc·lock, oc·vote, oc·stamp, oc·agent, oc·pledge, oc·fleet) listed with role + identity-binding + state. Wallet-persona MeNav surfaces the link · users discover the cross-family fact without hunting.
  • > §7 phase-1 · per-agent-class pricing · IntegratorEventConfig.agent { site_pays?, user_share_pct?, refuse? } applies when an event is fired with is_agent=true. computeFees handles the override; agent_refused throws → 422 from /api/integrator/event + /event/batch. Canonical envelope bumps to v=3 only when is_agent=true · human-fired events stay v=2 with byte-identical hashes. SDK side: @orangecheck/me-client v0.13.0 surfaces is_agent on fire + fireBatch.
  • > §7 phase-2 · agent override UI in /me/projects/[id] ConfigEditor · collapsible "agent class override" panel per-event-type with site_pays / user_share_pct / refuse controls. /verify/[id] shows a 🤖 agent-fired badge when an envelope carries is_agent=true so verifiers see the provenance at a glance.
  • > §7 phase-3 · cross_integrator_human_event_count scope · single events fetch serves both the existing total and the new human-only variant (filters is_agent !== true) without duplicating reads. SDK Scope union v0.14.0 catches up; /me/scope-grant preview shows what each scope reveals before the user grants.
  • > §7 follow-up · /scale agent vs human split · public dashboard now reports agent-fired event-rate alongside human · per-minute KV bucket pair for each. honest signal that agent volume is becoming a first-class capacity dimension.
  • > §6 phase-1 · trust attestation infrastructure (reputation graph) · TrustAttestationEnvelope (v=1, kind oc-me-trust) lets an integrator publish good/caution/block status about an oc identity that interacted with their surface. Three KV indexes (by_id, by_subject, by_issuer) keep newest-first reads O(1). POST /api/integrator/trust-attestation (owner-gated · 60/min/IP + 100/min/project) · GET /api/me/trust-attestations (session-gated · summary counts + distinct_good_issuers). /me/identity tier tab renders TrustAttestationsCard with per-row severity tone.
  • > §8 phase-1 · public /operators marketplace track-record surface · aggregates every distinct operator pubkey we've seen on guardian seats. Each row: federation count + first-seat date + per-fed compliance state + bootstrap-mode flag. Sort: most-active first. CORS-open at /api/public/operators · the page a federation creator scans before picking co-operators in /me/operator/federations/new. Linked from /trust + footer.
  • > §5 phase-1 · time-bounded auto-renew on continuous use · ScopeGrant gains last_used_at (debounced 1/hr) + auto_renew (default true for time-bounded). touchAndMaybeRenewGrants fires-and-forgets after every integrator event ingest, batch ingest, /scopes poll, and /api/family/scopes/<verb> read · long-running grants (90d default) extend automatically while in use, expire cleanly when the integrator goes silent. /me/identity grants tab surfaces "auto-renew while in use" toggle + "last used N days ago"; PATCH /api/me/scope-grants flips the flag without revoking.
  • > §10 phase-1 · cross-family scope grants · sibling products (vote.ochk.io, stamp.ochk.io, agent.ochk.io, attest.ochk.io, lock.ochk.io) consult cross-family scope grants from a reserved family:<verb> project_key namespace via GET /api/family/scopes/<verb>. Same store, same revoke, same audit log as integrator-side grants — just allowlisted by verb + Origin-reflection CORS for *.ochk.io credentials. /me/scope-grant detects family: prefix and renders sibling-product chrome on the consent prompt; /me/identity grants tab shows family badge per row; /me/family per-sibling CTA jumps to the consent flow with prefilled scopes (cross_integrator_human_event_count + attest_tier). Per-sibling state badge ("✓ N grants · manage" vs "grant cross-family scopes") reflects whether the user has already granted.
  • > @orangecheck/me-client v0.15.0 · oc.family.scopes(verb) helper for sibling-side use · structurally identical to oc.scope.granted({ project_key }) but the project_key is implied from the verb. Browser-side cookie credentials, optional staging-origin override, runtime allowlist of the 5 family verbs.
  • > §6 phase-1 · per-federation min_bond_sats_floor charter parameter · Federation interface gains optional min_bond_sats_floor (defaults to 100,000 sats network baseline). Validator emits warning when set below baseline (federations may consciously run lower as a documented trade-off, but /federations/[slug] + /compliance surface the choice). Phase-2 (deferred to V3-§9) wires charter-amendment voting via oc-vote so federations can escalate the floor as treasury value grows.
  • > §6 phase-2 · trust_attestation_count selective-disclosure scope · 4-int quad (total / good / distinct_good_issuers / caution) flows when the user grants; full bundle stays private. Combine with attest_tier (bond) and cross_integrator_human_event_count (paid-action history) for a layered sybil gate · "bonded + active + attested." Server-side resolver in scope-resolver, /me/scope-grant preview shows the user their own quad before granting, /me/transparency export gains a `trust_attestations` block with per-row signatures verifiable offline.
  • > @orangecheck/me-client v0.16.0 · trust_attestation_count Scope union + parseTrustAttestationCount() typed parser for the wire-format quad. Liberal on parseInt of fractions (the wire format never emits them; defensive).
  • > §6 phase-1 · /me/projects/[id]/trust integrator dashboard · publishing surface for the reputation graph · subject + status (good/caution/block) + note + expires_at form, summary stat strip, records list (newest first; revoke per row; verify ↗ link). New owner-gated GET /api/me/projects/[id]/trust-attestations + DELETE /api/integrator/trust-attestation/[id]. Past envelopes still verify against their original signatures; revocation is a metadata patch the live consumers exclude going forward.
  • > /verify/[id] handles trust-attestation envelopes alongside events + rebinds · TrustView component renders status badge, issuer + subject + occurred_at + note + expiry/revocation metadata, the LiveVerifier block (replays the envelope sig in-browser against the published JWK), the canonical envelope JSON, and a "what this proves" aside framing the selective-disclosure model. Closes the verifier loop · attestation IDs from /me/projects/[id]/trust or /me/identity tier tab now resolve like any other envelope ID.
  • > 587 tests passing across the platform.

live verifier · developer dashboard · sdk 0.4.0.

v1.0.42026-04-30
  • > live envelope verifier at /verify/[id] — runs all four steps (canonicalize, sha-256, fetch ochk.io/.well-known/jwks.json, verify Ed25519) entirely in the browser. only OC-controlled byte in the path is the published JWK.
  • > @orangecheck/me-client v0.4.0 published — adds oc.config CRUD, oc.webhook.verify (using @noble/curves with JWKS auto-fetch), oc.delegation issue/revoke, useOcSession re-export. SDK reference at docs.ochk.io/me/sdk.
  • > production-shape API endpoints — /api/payment/authorize, /api/session/{create,refresh,invalidate}, /api/me/projects (multi-tenant integrator), /api/me/profile, /api/integrator/event, /api/integrator-config.
  • > /me/wallet QR codes for receive + send invoice preview + withdraw with address classification + sweep vs bridge tabs.
  • > /me/settings persists every preference to localStorage via usePref hook.
  • > /status page now runs six client-side reachability probes every 60s against the actual observable surfaces.
  • > @orangecheck/oc-attest-protocol v1.2-draft-1 (FEDERATION-CUSTODY.md) — additive extension defining federation-custody descriptors, M-of-N graduation envelopes, guardian rotation. Backs me.ochk.io federation-custody claim with protocol-level structure.
  • > 71 invariant tests passing.

me.ochk.io launches.

v1.0.02026-04-30
  • > consumer commercial surface of orangecheck. the bitcoin-backed online identity that pays you to use it.
  • > three-class billable event taxonomy: class A (state-transition), class B (action-bound), class C (session). signin within an existing session is free.
  • > integrator-configurable pricing: every site sets its own per-event prices and user-share split. oc takes a fixed 20% platform fee.
  • > four sign-in paths: email/phone with federation-custodied wallet, BIP-322 wallet connect, federation-member sign-in, existing OC identity from any sibling site (cross-subdomain oc_session).
  • > authenticated app surface at /me, /me/wallet, /me/transactions, /me/identity, /me/earn, /me/projects, /me/operator, /me/settings, /me/graduate.
  • > public verifier at /verify and /api/envelope/[id]. published abuse-rate-limit table at /security and /trust.
  • > charter pinned identical to fleet.ochk.io/charter, ratified v1 · 2026-04-28.