Hello @Fortinbras , I took a look at both internal and external documentation and here is what I found.
Short answer: your instinct is right. There's no AppKit plugin that hands you optimistic concurrency or audit history as a feature. Those belong in the database and a small, explicit write API. AppKit's job is the plumbing around them: OAuth token refresh for Lakebase, an authenticated proxy to your Model Serving endpoint, on-behalf-of execution, and telemetry.
The one design question to settle first: is Delta the system of record with Lakebase as an edit buffer, or is Lakebase the record for interactive overrides with a governed sync back to Delta? For forecast overrides I'd pick the first. Keep the base forecast in Delta, bring it into Lakebase as a synced table (read-only on the Postgres side), and put user overrides in a separate writable Postgres table. Serve the app from a view that joins the two. This two-table pattern came up in an earlier Lakebase thread and it keeps you from fighting the sync pipeline: https://community.databricks.com/t5/lakebase-discussions/how-to-access-a-delta-table-in-uc-from-lake...
The write path is plain Postgres. Add a row_version to the overrides table. The client sends back the version it read, and you update only where key and version still match. Zero rows updated means someone got there first, so return a 409 and let the UI refetch and reconcile. In the same transaction, insert into an append-only audit table: actor, timestamp, request or correlation ID, business key, old and new values, reason or source (ui or agent), and validation result. Two statements, one transaction, done.
On plugins, two touch Lakebase and the difference matters here:
For a governed write-back where you need to know who changed what, use lakebase() with your own routes and stamp the forwarded user identity on every write.
Getting overrides back to Delta: Lakebase Change Data Feed (Public Preview) streams every insert, update, and delete into lb_<table>_history Delta tables with pre- and post-images, so you get a platform-managed audit trail for free. The app-level audit record is still worth keeping since CDF can't capture the who and why. For the gold table itself, run a Lakeflow Job that reads the overrides table through the Unity Catalog registration and does a MERGE, with bounded retries and a user-visible conflict path if it collides with another writer. Docs: https://docs.databricks.com/aws/en/oltp/projects/lakebase-cdf and https://docs.databricks.com/aws/en/oltp/projects/databricks-apps
On the agent: it should never write. Have the LangChain agent return a typed change set (row keys, field, old value, new value, reason). Validate authorization, allowed fields, types, business rules, and the forecast version in a backend tool. The UI shows a diff, the human clicks apply, and it goes through the same versioned route as a manual edit. One write path, one audit log, human in the loop by construction. The serving() plugin handles the proxy and streaming: https://developers.databricks.com/docs/appkit/v0/plugins/model-serving
AppKit versus Dash: both run fine on Databricks Apps, and there are Dash, Flask, and Streamlit Lakebase templates if you go Python. Dash means you hand-build the token refresh and serving proxy that AppKit ships with. Don't switch to solve concurrency or audit; those live in the service and database layer either way. Pick the language your team will still want to maintain in a year.
Honest caveat: I haven't run database() in production myself and it's Beta, so APIs can move. The lakebase() pool and the synced-table pattern are the stable ground.
More reading: https://developers.databricks.com/docs/apps/overview and https://docs.databricks.com/aws/en/lakehouse/acid
Regards,
Louis