Last week I said Quonfig was ready for someone to try. This week the first real customers actually did, and most of what shipped came out of watching them use it — the navigation that felt slow, the editor that fought back, the operators that weren't there yet. The kind of week you only get once people are in the product.
What Moved This Week
The first real customer migrations off Launch landed. We've got workspaces that have come over end-to-end against the live infrastructure, and caught some issues that staging dress rehearsals hadn't caught The migrator has now made the trip on real customer data.
Cmd-K palette. Hit ⌘K (or Ctrl-K) anywhere in the app and you get a search palette with two modes: Find — fuzzy search across every flag, config, schema, segment, and page in your workspace; and Do — actions like "create flag", "switch workspace", "go to billing". Fuse.js handles scoring; the manifest invalidates correctly after mutations so a flag you just created shows up immediately. This is the thing I've wanted since week one and it's the new way I navigate the whole app.

The Java SDK is back. A clean greenfield port — Java 17, JDK java.net.http for HTTP and SSE (no okhttp), Jackson for JSON, Guava for the Murmur3 hash. All 27 targeting operators, AES-GCM env-var decryption, primary→secondary failover, datadir mode, telemetry pipeline with eval-summary aggregation and example-context sampling, the whole thing under a Quonfig / BoundQuonfig API that mirrors the other SDKs. 320 tests passing including the full integration-test corpus. PR #1 is open for 0.0.1 to Maven Central — once it merges, com.quonfig:sdk-java:0.0.1 is live and the JVM languages have a real home in Quonfig again.
Metered billing wired end-to-end through Stripe. Real-edge metering from api-delivery into ClickHouse, daily ETL job uploads usage to Stripe meters, webhook keeps subscription state in sync, a requireBillingActive middleware gates writes when something's wrong, and customers get a /usage view plus one-click handoff to the Stripe Billing Portal. Live in dogfood today; Phase 2 rollout is gated on the soft-launch date.
Flag lifecycle actions. A flag row's kebab menu now has "Ready for cleanup" (marks a flag for retirement without removing it — surfaces in a status filter so engineers can see what's safe to delete) and "Convert to permanent config" (turns a fully-rolled-out boolean flag into a permanent config in a single git-aware commit so history is preserved). Two of the most-asked-for actions in any flag tool, finally first-class.
qfg activity namespace in the CLI. A whole new top-level command for inspecting recent change history without opening the dashboard:
qfg activity feed # workspace-wide change feed
qfg activity history my.flag # full history of one flag
qfg activity deleted # tombstone list
qfg activity restore my.flag # bring it back
With audit-log, history, and log as aliases for the friction-log phrasings.
qfg run — the last piece of the secrets puzzle. Quonfig has handled secrets cleanly for any code that talks to the SDK. But some libraries — database drivers, OTel collectors, Redis clients, half the JVM ecosystem — flat-out insist on being initialized from environment variables, and there was no clean way to get a Quonfig-managed secret into one of those without a hand-rolled shim. qfg run closes that gap. It resolves Quonfig configs, exports them as env vars, and execs your command:
qfg run DATABASE_URL:db.url STRIPE_KEY:stripe.secret-key -- node server.js
For larger sets of vars, drop the mapping into a .qfg-env file and just:
qfg run -- node server.js
CI, package.json scripts, local dev, anywhere a process expects env vars — Quonfig is now the source of truth without the receiving code knowing or caring.
Schema "Used by" everywhere it should be. The schemas list and detail pages now show which configs reference each schema, with an "Add config using this schema" shortcut on the detail page that pre-selects the schema on the new-config form. Closes the loop between defining a schema and using it.
A real JSON editor — SO MUCH BETTER. The textarea I've been suffering with for the last month is gone. In its place: CodeMirror with full syntax highlighting, line numbers, fold gutters, bracket matching, and live meta-schema autocomplete that suggests the next valid key as you type. The same editor renders raw-JSON config values, the schema-document editor, and the read-only viewer on config detail pages. Save is blocked when your JSON is mid-edit-invalid (with a tooltip telling you why instead of silently saving the last-known-good value behind your back), the Form ⇄ Raw toggle preserves your in-progress text instead of nuking it, and the read-only viewer is now click-to-edit so it stops looking like a dead zone you can't interact with. Editing JSON in Quonfig finally feels like editing code, which is what it always should have been.

Inline rules in the config list. Every targeted rule per environment now renders inline with its actual value, instead of collapsing to a "Targeted" badge that you had to click into to see. Confidential values mask, JSON values pretty-stringify. The flags table now shows you what your config actually does without a hover or a click.
IS_PRESENT / IS_NOT_PRESENT targeting operators across every SDK. "Show this experiment to anyone with an email" no longer requires a IS_NOT_NULL-with-empty-string-gotcha workaround. Released as sdk-go@v0.0.19, quonfig@0.0.13 (Ruby), and bumped through every OpenFeature provider. Empty string, 0, and false are intentionally present — only missing keys and nil are absent. Operator picker in the dashboard updated to match.

Evaluation details (variant, errorMessage, flagMetadata) across every SDK + OpenFeature provider. For OpenFeature users this means a real ResolutionDetails with the variant string, structured error code (no more inferring from error message strings), and metadata like which rule index matched and which split bucket you landed in. Shipped consistently across Node, Python, Ruby, Go, JavaScript, and Java.
A multi-context detail page. Click any row in Recent Contexts and you land on a per-context detail view showing every flag/config evaluation for that context, with inline override controls (dropdown for boolean, text for string, etc.) right where you're looking at the value. No more bouncing between contexts and flags pages to test what a specific user sees.
Better error messages when verify rejects a push. Pushes that get rejected by the workspace's qfg verify hook now surface as 422 UNPROCESSABLE_CONTENT with the failing file and field path in structured data, instead of a generic 500. The dashboard, the CLI, and any oRPC client get the same actionable error.
Where That Leaves Us
We've crossed from "can be tried" to "is being used." Real customers working on migrating, the billing pipeline is live in dogfood, the JVM is back on the supported list, and the day-to-day app navigation finally feels as fast as I want it to.
Rest of May is just continuing polish and harderning. Taking a real crack at some chaos testing for the SDK now.
Still targeting 1.0.0 SDK and GA for end of May. But there's not really anything on the must fix list.
-- Jeff
Want to try it?
Quonfig stores your config in git. Feature flags, dynamic config, log levels, and secrets — all as files you own.