changelog

rss feed

what landed, in reverse chronological order. one entry per shipped change worth knowing about — security, features, infrastructure, fixes.

briven ran dogfood-first through the first half of 2026 and graduates to public beta on 2026-05-21. everything prior is internal validation on j's own products; everything after is open to anyone with a credit card.

may 2026

  • featdocs

    AI.md operator setup guide + per-feature model overrides

    docs/AI.md (tracked in repo alongside docs/MIGRATION.md) documents which ollama model to run, why qwen2.5-coder:32b is the default, how to differentiate models per feature, hardware sizing reference, what NOT to pick. four new env vars — BRIVEN_OLLAMA_MODEL_SCHEMA / _FUNCTION / _EXPLAIN / _DOCS — each falls back to BRIVEN_OLLAMA_MODEL when unset so single-model operators don't need to set them. logs now record the actual model used per request (not the global default).

  • fix

    mobile responsive pass — dashboard nav, project tabs, marketing footer

    project tabs row (14 secondary tabs inside a project — overview / functions / logs / etc.) now horizontally scrolls on mobile instead of overflowing; sidebar hides below md and a horizontal nav strip appears at the top of the dashboard so projects / teams / billing / settings stay one tap away on phones. admin stats grid + project overview cards + invoke-panel grid all gain responsive col counts. subprocessors table wraps in overflow-x. marketing footer rewritten as a proper five-column nav (brand + product + docs + legal) on top of a thin bottom strip with copyright + flndrn limited + heart-in-flanders. fixed dashboard body padding so phones get the full viewport width.

  • feat

    briven ai cli — schema / function / explain from the terminal

    `briven ai schema "..."`, `briven ai function "..."`, `briven ai explain --file <path>` proxy to the same three api endpoints the dashboard hits. takes a prompt as a positional arg, writes to stdout (or `--out path`). `briven ai function --with-schema` pulls the project's current schema snapshot in as model context. exit code 2 means the api host hasn't wired BRIVEN_OLLAMA_URL — a clear "AI assistant offline" message instead of an opaque http error. completes the AI surface: api + dashboard + cli all wire to the same self-hosted Qwen 2.5-coder backend.

  • featdocs

    docs search + corpus index (AI assistant pre-staged)

    new endpoint at /api/search?q=… returns the top N docs pages by word-overlap against a hand-curated corpus (27 entries covering every published page). /search renders the same results as a browseable page with a search box. when the ollama backend lands the AI docs assistant wraps this same ranking — the search picks the top 3 pages, the assistant forwards them to the model as system-prompt context.

  • docs

    migration · mongodb → briven

    new page at /migration/mongodb. covers the decision matrix for keeping embedded docs as jsonb vs flattening into separate tables, ObjectId → text + ulid for new ids, the mongoexport → transform-script → COPY data move, find/aggregate → ctx.db chain rewrites, and the 2+ week parallel-run window mongo → relational migrations need to catch shape mismatches.

  • feat

    ai explain code — third feature in the AI trifecta

    paste any briven schema or function snippet, get a plain-english walkthrough in briven idioms (what the wrapper means, which db calls happen, where reactivity hooks in, sharp edges). same self-hosted Qwen 2.5-coder backend + same not-logged privacy posture as schema/function gen. dashboard surface at /dashboard/projects/:id/ai-explain. third tab in the AI section.

  • docs

    per-source migration sub-pages — drizzle + prisma

    two new pages on docs.briven.tech: /migration/drizzle and /migration/prisma. each covers schema-column mapping, indexes, data export (pg_dump + pg_restore), the functions-port rewrite (drizzle's db.select chains and prisma's findMany calls both become ctx.db chains), auth hand-off to the nextauth guide, and reactivity as a new capability. the /migration overview separates them out of the lumped "raw postgres / drizzle / prisma" entry now that each has its own page.

  • feat

    ai function generator — companion to ai schema

    natural-language → draft briven/functions/<name>.ts. /v1/projects/:id/ai/generate-function takes { prompt, schemaContext? } and forwards to ollama with a system prompt baking in the @briven/cli/server DSL (query / mutation / action wrappers, ctx.db chains, brivenError shape, ulid prefixing). dashboard surface at /dashboard/projects/:id/ai-function ssrs the current schema snapshot into a compact "table { col: type PK NOT NULL -> fk }" summary the model reads as context. the same not_configured 503 + privacy stance as the schema generator: prompts and responses are not logged.

  • feat

    tier-aware realtime subscription cap + project cap-warning banner

    TIERS.concurrentSubscriptions (free=100 / pro=1000 / team=10000) is now enforced by the realtime service, replacing the platform-wide env ceiling. realtime resolves the cap from a new internal endpoint /v1/internal/projects/:id/limits on first subscribe per project (5-min cache, shared-secret gated). project overview page grows a yellow/red banner at 75%/90% of the cap so the user can upgrade before subscribes start getting rejected; banner sources from a new /v1/projects/:id/realtime-stats endpoint scoped to the caller's own project. admin · realtime page auto-refreshes every 10s via meta refresh so an operator can keep it open while watching a noisy project.

  • feat

    admin · usage — retry skipped polar pushes

    when polar push rows land in `skipped` (missing meter id, bad customer mapping, durable 4xx), the operator had to UPDATE usage_events directly in psql to re-enable them. now /dashboard/admin/usage grows a "retry → pending" button (window: 1/7/30/90 days) that flips skipped rows back to pending in one click. window is bounded server-side so a runaway click can't re-push years of stale data. action is audit-logged with the row count.

  • feat

    admin · realtime — live subscription snapshot

    new admin page at /dashboard/admin/realtime shows per-project subscription counts + per-channel refcounts + the current cap values, with severity coloring at 60% and 90% of the per-project cap so an operator can spot a noisy project before it gets clamped. backed by a shared-secret-gated /v1/realtime/stats on the realtime service (no PII leaked — only project ids and channel names). 503 with a clear "not configured" state when the realtime URL or shared secret is unset.

  • security

    subscription caps on realtime — per-ws + per-project

    realtime now refuses subscribe frames past BRIVEN_REALTIME_MAX_SUBS_PER_WS (default 200) and BRIVEN_REALTIME_MAX_SUBS_PER_PROJECT (default 10,000 — the year-one platform ceiling). counter briven_realtime_subscribe_rejected_total{reason="ws_limit"|"project_limit"} lights up on /metrics so an operator can spot a runaway client. error frames carry the offending subscriptionId so the client can correlate. closes the "single bad ws can exhaust 10k concurrent subs" surface noted in BUILD_PLAN §7.4.

  • feat

    connection-seconds in usage + tier caps

    TIERS now ships connectionSecondsPerMonth (1M / 10M / 100M for free / pro / team) and concurrentSubscriptions (100 / 1000 / 10000). hourly aggregator scrapes briven_realtime_connection_seconds_total from the realtime /metrics endpoint, diffs per project, writes connection_seconds rows to usage_events (the polar push worker already drains them). dashboard usage card now shows realtime usage alongside invocations + storage + compute, formatted as s/m/h/d so a Team plan reads as "115d / 1158d" instead of an unreadable 100 million seconds.

  • feat

    polar meter push: real fetch + org→customer resolution

    the metering worker no longer logs intent — it actually posts to polar. customer ids resolve through project → org → subscriptions.polar_customer_id (5-min in-process cache, invalidated on the polar webhook so a fresh checkout takes effect on the next tick). 5xx + network errors leave the row pending for the next minute; 4xx marks the row skipped so it doesn't loop forever. invocations + storage_bytes flow today; connection_seconds queued for the realtime /metrics scraper.

  • feat

    storage caps on every tier, surfaced through usage

    TIERS now ships storageBytes alongside projectsPerOrg / functionsPerProject / invokesPerMonth: 1 GiB on free, 10 GiB on pro, 100 GiB on team. dashboard usage card shows "used / cap" — pg_total_relation_size sampled live against the project schema, excluding the platform's _briven_* bookkeeping.

  • security

    project-suspension gate mounted globally

    blockIfProjectSuspended is now mounted once at /v1/projects/:id/* instead of sprinkled per-router. read methods (GET/HEAD/OPTIONS) skip the check so dashboards stay readable while a project is being investigated; every mutation route (env writes, member moves, studio writes, db shell, deploys, invokes) inherits the gate without per-route wiring. closes the drift risk where a new route lands without picking up the suspension check.

  • featsecurity

    account deletion (gdpr article 17) — 30-day soft-delete cascade

    settings · danger zone now ships a real account-deletion flow. typed-email confirmation gates the click; the api revokes every session, every api key on sole-ownership projects, and every pending invitation the user sent. sole-owner orgs (personal + any team where the user is the only owner) and the projects under them soft-delete. multi-owner team orgs survive — the user is just removed from membership. PII clears in the same transaction (legal name, address, VAT, company, display name, image); id + email + createdAt stay so audit-log FKs survive. confirmation email lands before the cascade runs. a daily 03:30 UTC worker hard-deletes rows past the 30-day grace window; FK CASCADE handles the rest. polar subscriptions are NOT auto-cancelled — manage via the polar portal during the grace window.

  • infra

    alertmanager + discord bridges in the observability stack

    prometheus alerts now route through alertmanager → benjojo/alertmanager-discord bridges → two discord channels. severity=critical|warning lands in #briven-alerts (page-worthy); info lands in #briven-deploys. operator pastes DISCORD_WEBHOOK_ALERTS + DISCORD_WEBHOOK_DEPLOYS into the dokploy env; the bridges hold them inside the docker network so urls never leave the host. group_wait 30s, group_interval 5m, repeat_interval 4h, plus an inhibit rule so a critical for (service, alertname) suppresses redundant warnings.

  • docs

    http api reference at /docs/api

    every public endpoint grouped by area (invoke, realtime, projects, deployments, studio, logs + stats, usage, api keys, project members, orgs, billing) with method, path, and a one-line summary. linked from the docs sidebar.

  • feat

    studio polish: ALTER COLUMN, TRUNCATE, schema overview, project move, invocation sparkline

    ALTER COLUMN endpoint toggles nullability and changes/drops default expressions with a 2-mode PATCH (rename OR alter). TRUNCATE TABLE button (RESTART IDENTITY, opt-in CASCADE) for wiping rows without dropping the schema. New /studio/schema page renders every table in one canvas with FK arrows + inbound references. Project settings grows "move to another team" — re-parents a project across orgs after verifying target-org membership. Project overview gains a 24-hour invocation sparkline (server-rendered SVG, no client JS) with red overlay for errors.

  • feat

    function logs + per-function stats in the dashboard

    new /logs tab on every project surfaces function_logs (already populated by the runtime log-fanout worker) with chip filters per function and ok/err status, cursor-based pagination, and a JSON export that walks the cursor for up to 1000 rows honoring the active filter. Per-function stats badge on the functions tab shows last-24h count + error rate + p50/p99 duration via a single percentile_cont query. Project overview surfaces last 5 errors in a red-tinted card with a deep-link to the filtered logs view.

  • feat

    dashboard-managed schemas — convex-style manual database creation

    studio gains the full DDL surface: + new table with typed columns (text/integer/bigint/boolean/timestamptz/jsonb/uuid/numeric), primary keys, foreign keys with ON DELETE behavior, defaults; add/drop column on a live table; create/drop indexes (multi-column + unique). Schema panel renders relationships as “→ users.id”. FK values in the data view become “↗” links to the referenced row. Copy-as-schema.ts generates the equivalent briven/schema.ts so anything you click can graduate to git. SQL editor at /studio/sql runs arbitrary statements scoped via SET LOCAL ROLE to the project owner role, 5s statement_timeout, every query audit-logged. New connect tab shows project endpoints + a button to issue a 15-minute shell DSN for psql / pgcli / external tools. CLI path unchanged; both write to the same schema.

  • feat

    team org admin — invitations, members, role change, delete

    team owners can now invite collaborators by email (mirrors project_invitations: 7-day hashed-token email link, accept page at /dashboard/org-invitations/accept), list current members, change roles inline (with last-owner protection), remove non-owners, and soft-delete a team org (refused while live projects still exist). Tier-aware: free tier = 1 personal org, no team creation; pro/team = unlimited. Dashboard surfaces pending team invites in the projects banner alongside project invites.

  • feat

    AI schema generator — Phase 3 differentiator

    POST /v1/projects/:id/ai/generate-schema accepts a natural-language prompt and returns a draft briven schema.ts via a self-hosted Qwen 2.5-coder 32B running on briven infrastructure (no third-party AI provider). Dashboard surface at /dashboard/projects/:id/ai-schema with a copy button. Gated on BRIVEN_OLLAMA_URL — service shows a friendly "AI assistant offline" message until configured. Prompts and responses are not logged.

  • feat

    github + konnos OAuth credentials live on briven.tech

    all three OAuth providers (Google + GitHub + Konnos) now have their credentials configured in the production env. signin page shows all three buttons; existing magic-link flow continues to work in parallel.

  • feat

    polar billing wired end-to-end

    production polar configured: access token, webhook secret, and product IDs for briven Pro ($21.99/mo) and briven Team ($99.99/mo). Existing webhook receiver at /v1/billing/webhook now authoritative for tier sync — subscription.* events flip projects.tier in the same transaction. checkout flow + customer portal both live.

  • docs

    migration guide: nextauth / auth.js → briven

    sixth per-source migration page. schema maps 1:1 (both target Better Auth's shape); the work is the api shape (getServerSession → brivenServer.session(), useSession imports). covers account preservation strategies, provider port, callback hooks, and the cutover checklist.

  • feat

    usage metering: hourly aggregation cron + usage_events table

    phase 3 GA-blocker progress. startUsageAggregator() runs ~5min after every wall-clock hour and writes one usage_events row per (project, hour, metric) for invocations + storage_bytes. Idempotent via the unique index, so a catch-up re-run after a restart is safe. Polar metering push is a separate worker landing once meter IDs are configured.

  • feat

    realtime connection-seconds metric per project

    apps/realtime tracks per-project cumulative subscription-seconds (closed subs + live deltas) via briven_realtime_connection_seconds_total{project} on /metrics. Drives the eventual Polar metering push for connection-minutes billing.

  • feat

    project auto-suspension on abuse-report resolution

    projects.suspended_at column + blockIfProjectSuspended() middleware on invoke + deploy routes (403 project_suspended). The /v1/admin/abuse-reports/:id PATCH endpoint now accepts an optional projectId; resolving with resolution=suspended or banned flips the project in one step. Manual /v1/admin/projects/{suspend,unsuspend} endpoints for the non-abuse paths. Admin triage modal in the dashboard surfaces the new projectId input only when the resolution implies suspension.

  • feat

    github + konnos OAuth alongside google + magic link

    sign-in page now wires four auth methods: magic-link via email, Google OAuth, GitHub OAuth, and Konnos OAuth (Forgejo at code.konnos.org via the generic-oauth plugin). Each button is gated by NEXT_PUBLIC_BRIVEN_HAS_*_OAUTH so the UI hides providers whose creds aren't configured.

  • fix

    /info reports a real sha on dokploy auto-deploys

    health.ts now resolves the commit sha from .git/HEAD when BRIVEN_BUILD_SHA isn't passed at image build time (which is exactly the case for dokploy auto-deploys). loose refs + packed-refs both supported. Paired with treating the literal "dev" env value as "fall back to git" sentinel. Promoted to @briven/shared so apps/realtime + apps/runtime use the same chain.

  • feat

    deploy_history table + /dashboard/admin/deploys

    every api boot now writes one row into deploy_history (service, buildSha, buildAt, env, bootedAt). new admin page renders a timeline with "live" badge on the most recent row so operators can correlate "the bug appeared at 14:32" with "deploy abc1234 went live at 14:30" without ssh-ing to the box. /v1/admin/deploys?service=api&limit=N exposes the raw stream.

  • docs

    migration guide: hasura → briven

    fifth per-source migration page. postgres half ports for free via pg_dump; the work is the permissions port — every (role, table, action) triple from hasura metadata becomes a guard in function code. covers actions, event triggers, scheduled triggers, remote schemas, auth (preserve-ids vs preserve-jwts) and subscriptions vs briven's reactive useQuery.

  • feat

    deploy_history table + /dashboard/admin/deploys

    every api boot now writes one row into deploy_history (service, buildSha, buildAt, env, bootedAt). new admin page renders a timeline with "live" badge on the most recent row so operators can correlate "the bug appeared at 14:32" with "deploy abc1234 went live at 14:30" without ssh-ing to the box. /v1/admin/deploys?service=api&limit=N exposes the raw stream.

  • fix

    /info reports a real sha on dokploy auto-deploys

    health.ts now resolves the commit sha from .git/HEAD when BRIVEN_BUILD_SHA isn't passed at image build time (which is exactly the case for dokploy auto-deploys). loose refs + packed-refs both supported. paired with treating the literal "dev" string as a "fall back to git" sentinel since that's the dockerfile ARG default.

  • infra

    observability stack live + postgres-exporter sidecar

    grafana / loki / prometheus / promtail running on briven.tech kvm4 as compose project briven-obs; postgres-exporter ships pg_stat_* metrics from briven-postgres. all five prometheus jobs (api / runtime / realtime / postgres / prometheus) report up; four starter dashboards (api requests, runtime invocations, realtime subs, postgres health) populated.

  • feat

    mittera email suppression layer

    new email_suppressions table + service. mittera webhook handler dispatches permanent bounces / complaints / mittera-suppressed events into the suppression list; outbound send short-circuits on suppressed recipients before posting to mittera. admin ui at /dashboard/admin/email-suppressions with manual add / remove.

  • feat

    mittera outbound + webhook live on briven.tech

    POST https://api.mittera.eu/api/v1/emails with Bearer auth verified end-to-end (smoke + magic-link both 200). inbound webhooks at https://api.briven.tech/mittera-webhook verify X-mittera-Signature: v1=<hex> + X-mittera-Timestamp: <ms> with a 5-minute replay window, dispatch per spec §6, audit-log every event.

  • feat

    nightly backup cron on kvm4

    systemd timer fires /usr/local/bin/briven-backup.sh daily at 02:17 UTC. pg_dump --format=custom against briven-postgres for both briven_control + briven_data, 30-day local retention, off-site upload gated on /etc/briven/backup.env (BRIVEN_BACKUP_S3_*). off-site disabled until B2/R2 creds land.

  • feat

    briven init --template={blank,todo-app,chat}

    cli init now scaffolds from one of three inline templates. blank = minimal notes; todo-app = 4 mutations + 1 reactive query; chat = two-table per-room reactive. templates are embedded so init works on a fresh machine with no network.

  • feat

    briven doctor + GET /info build identity

    doctor now pings /info (new endpoint) and reports build sha + build timestamp + uptime alongside the existing health / ready / auth checks. Dockerfile passes BRIVEN_BUILD_SHA + BRIVEN_BUILD_AT through as ARGs for compose to inject.

  • feat

    admin: email events + suppressions dashboards

    two new pages under /dashboard/admin — email-events (last 200 webhook deliveries with severity-tinted chips) and email-suppressions (recipients we won't send to, with manual add / remove). both gated on is_admin.

  • infra

    forgejo actions ci

    .forgejo/workflows/ci.yml runs pnpm -r lint + typecheck + test on every push to main. real eslint config replaces 13 lint stubs; 15 packages green workspace-wide.

  • chore

    briven.cloud → briven.tech sweep (78 files)

    every public-facing reference to the placeholder briven.cloud domain replaced with briven.tech. scripts/swap-domain.sh ships as the rename helper for future cutovers.

  • feat

    @briven/svelte + @briven/vue clients

    svelte stores (query / mutation, reference-counted by svelte's store contract) and vue 3 composables (useQuery / useMutation, onScopeDispose-cleaned). same shape as the react hooks; same setBrivenClient bootstrap.

  • feat

    briven export / briven import

    briven export writes a project's schema + functions to a json archive; briven import reads the archive back into a target project as a deployment. data movement (pg_dump streaming) follows in a later slice.

  • feat

    briven projects (list + set-default)

    list projects authenticated on this machine; set the local default that other commands fall back to when there's no briven.json. zero server round-trip — works against the per-project api keys the cli already stores.

  • feat

    studio (read mode)

    embedded data browser at /dashboard/projects/:id/studio. table list with approx row counts and storage size; per-table view with column metadata and paginated rows. admin-tier gated; identifier escaping prevents cross-schema reads.

  • infra

    observability stack + metrics endpoints

    grafana / loki / prometheus / promtail compose ships under infra/observability with four starter dashboards (api requests, runtime invocations, realtime subs, postgres health). /metrics now live on api + realtime; postgres-exporter sidecar template ready for the data plane.

  • feat

    restore drill (monthly cron)

    pulls the latest pg_dump off off-site storage, sha256-verifies, restores into a throwaway db, sanity-counts core tables, drops the db. systemd timer on the 1st at 04:30 UTC. non-zero exit fires the discord webhook.

  • feat

    public status page

    docs.briven.tech/status — live probes against api / runtime / realtime, red/green per service, latency + http status, no cache. dns cutover to status.briven.tech is a future ops move.

  • feat

    open-signups env flag

    BRIVEN_OPEN_SIGNUPS toggles invite-only beta vs. public signups across all three Better Auth paths (email+password, github oauth, magic link). cutover is now config-only, no code change.

  • docs

    sla matrix on /dashboard/billing

    uptime, response target, support response, rollback window — per tier. free best-effort; pro 99.5% / p99 < 500ms invoke; team 99.9% / p99 < 200ms invoke + 100ms RT fan-out.

  • chore

    metrics module promoted to @briven/shared

    createMetricsRegistry({help}) factory in @briven/shared/observability replaces three duplicated hand-rolled prometheus exposition modules in api / runtime / realtime. each app instantiates its own scoped registry; ~400 LOC of duplication retired.

  • featdocs

    public migration guide + public changelog

    docs.briven.tech/migration documents the five principles + ten-step playbook that every briven migration follows, with per-source teasers for convex / supabase / raw-postgres / firebase. this changelog ships alongside.

  • feat

    phase 3 abuse-report pipeline

    public POST /v1/abuse-reports (anonymous, rate-limited 5/min/IP via cf-connecting-ip) + admin GET/PATCH /v1/admin/abuse-reports for triage. severity (spam / phishing / malware / csam / tos / other) and resolution (no_action / warned / suspended / banned) frozen.

  • feat

    phase 3 beta-invite dashboard surface

    recipients can now see and accept pending invitations from /dashboard/invitations without going through the email link. the email-link flow stays intact for not-yet-signed-in recipients. accept-by-id replaces the token-based path inside the dashboard so the listing API never has to expose one-time tokens.

  • feat

    phase 3 usage-metering (invocations slice)

    GET /v1/projects/:id/usage returns invocation count + total duration for the current calendar month UTC, with optional ?from=&until= for custom windows. backed by aggregation over function_logs (no new event table needed for this slice).

  • feat

    tier-aware rate limits at the gateway

    rateLimit middleware now accepts a dynamic limit fn so caps can vary per project tier. RATE_LIMITS_BY_TIER table: invoke = 60 / 600 / 6000 per minute (free / pro / team), deploy = 5 / 30 / 100. wired onto the invoke and deploy routes; rollout to remaining mutations is the next pull.

  • featfix

    briven invoke command

    briven invoke <function> [--body <json>] [--body-file <path>] [--raw] is in the CLI. closes the dogfood smoke-test gap that previously required curl. --raw mode prints the unwrapped function value, jq-pipeable.

  • feat

    shared structured logger with redaction

    @briven/shared/observability exports createLogger(). every emitted line runs through the redaction pass — emails and IPv4 addresses can't leak into Loki even if a caller forgets to scrub at the call site. apps/api, apps/runtime, apps/realtime all delegate.

  • security

    constant-time shared-secret comparison

    the runtime shared secret is now compared with crypto.timingSafeEqual across apps/api/src/routes/internal.ts, apps/runtime/src/index.ts, and apps/realtime/src/index.ts. a remote attacker measuring response latency can no longer recover the secret byte-by-byte.

  • security

    rate-limit pinned to cf-connecting-ip outside dev

    rate-limit middleware now returns 403 origin_direct_rejected when BRIVEN_ENV !== development and cf-connecting-ip is missing. prevents bypass via direct origin hits (cloudflare-only ingress in production).

  • security

    BRIVEN_ENCRYPTION_KEY required at boot in non-dev

    previously failed-closed at request time when missing — a deploy could boot, only blowing up when the first customer read an encrypted env var. now fails loud at startup.

  • feat

    realtime LISTEN/NOTIFY pipeline complete

    apps/realtime now closes the loop: WS subscribe → LISTEN on per-table channels → NOTIFY → re-invoke → push fresh data. internal invoke route added on apps/api so realtime can use the runtime shared secret. fireChannel snapshot iteration prevents touchedTables drift from skipping subscribers mid-fan-out.

april 2026

  • security

    owner-tier scaffolding pinned (PR #20)

    reservation for future destructive routes (project delete, member removal). enforced via the project-auth chain.

  • security

    per-key role scoping for API keys (PR #19)

    human users can issue keys at their own role or lower (viewer / developer / admin). owner-tier is reserved for human owners and never assignable to a key.

  • security

    HTTPS-origin invariant fail-fast outside dev (PR #18)

    BRIVEN_API_ORIGIN and BRIVEN_WEB_ORIGIN must start with https:// when BRIVEN_ENV !== development. catches misconfigured prod deploys at boot.

  • fix

    realtime + runtime smoke tests (PR #17)

    bun-test smoke files so CI exits 0 with empty suites. closed the noise from CI runs that warned "no tests found".

  • security

    org-vs-project authz reconciliation (PR #16)

    effective-role gates resolve project-level role from org membership when the project doesn't carry an explicit member row. fixes a class of bugs where org owners couldn't access their own projects.

  • security

    cross-site CSRF closed on /v1/* state-changing routes (PR #15)

    sameSite=strict on the session cookie + Origin-check middleware. unsafe-method requests with a session cookie now require an allow-listed Origin.

  • security

    schemaSnapshot validator + bound migration insert (PR #14)

    closed a high-severity SQL-injection vector — the schema snapshot is now strictly validated before any DDL is interpolated.

  • security

    security hardening phase-0 (PR #13)

    better-auth secret rotation, audit-log IP pepper, IP redaction in logs, realtime WebSocket upgrade gate.

  • feat

    @briven/cli ships as a self-contained tarball (PR #10)

    tsup bundles the cli with @briven/schema, @briven/shared, @briven/config inlined. consumers install via pnpm add -D @briven/cli without the workspace-ref problem the prior file: install hit. exposes @briven/cli/schema and @briven/cli/server sub-imports.

  • feat

    briven link writes projectId into briven.json (PR #11)

    briven link --project <p_…> records the project id locally so subsequent commands (deploy, invoke, env, db) infer it without --project flags.

  • infra

    wildcard TLS via Cloudflare DNS-01 (PR #9)

    traefik issues *.apps.briven.tech certificates via the cloudflare DNS challenge. each customer project gets its own routable subdomain at deploy time.

  • fix

    auto-create personal org on signup + lazy backfill (PR #12)

    every user has exactly one personal org from the moment they sign in. /v1/me lazily backfills for older users who pre-date the change.