The hour you should only spend once
Getting a report right takes judgment. Which tables hold the truth, whether returns count against revenue, what baseline makes a Tuesday comparable to a Tuesday: an hour with an AI assistant settles questions like these well, because settling them is a conversation. By the end there is a report worth keeping, and a precise recipe for producing it.
Then the report needs to exist again next week, and the economics invert. Replaying the conversation spends tokens deriving what is already derived. It takes minutes of a model working through steps whose outcome is known, needs the assistant connected and the person present, and can come back subtly different: a changed rounding, a reworded label, an alternate join that looked equivalent. For work whose entire point is that it is settled, a model in the loop is cost without benefit.
Saving the conversation as a reusable prompt fixes part of this, and for work that needs judgment on each run, a prompt is the right tool. But a Tuesday flash report does not need judgment on Tuesday. It needs the same queries, the same arithmetic, and the same layout, delivered before anyone asks.
The automation gap in AI integrations
Most AI data integrations stop exactly here. The assistant can answer anything interactively, and none of it survives the conversation as something that runs by itself. The standing options both give up something essential: keep asking the assistant, and pay the interactive cost forever, or hand the logic to an engineering team, which turns a settled recipe back into a ticket, a repository, a deploy, and an owner, the same path that keeps one-off files out of warehouses.
Scheduled-report features in BI tools cover a narrow slice, for the dashboards that live inside them, built by the people licensed into them. What has been missing is the general form: the automation an assistant can write during the conversation where the logic was settled, that a business user then owns, inspects, and schedules without anyone opening an IDE.
A recurring report, two ways
A conversation per refresh
Ask the assistant again each time
- Every refresh replays the reasoning through a model, spending tokens on logic that was settled weeks ago
- The run takes minutes of agent time and needs the agent connected
- Two runs can phrase, round, or even join slightly differently
- Usage scales with the schedule: daily costs thirty times what monthly does
A conversation once
Saved as a script Plexara runs
- The assistant writes the settled logic down once; the platform executes it from then on
- No model in the loop: a run is queries and code, finished in seconds
- The same version on the same data produces the same report, every time
- Running it daily, or every minute, costs no more attention and no more tokens
A script the agent writes, the platform runs
A Plexara automation is a script: a small program in a dialect of Python called Starlark, stored on the platform, versioned like a document, and executed by Plexara itself. Your assistant already knows the language, and writes the script the way it would write any code, with one difference that matters: the platform checks the work before it goes live.
Validation parses the source and reports what it would reach, which queries, which connections, where output lands, so what a script does is readable without reading code. A dry run then executes it for real under the author’s own identity, with tighter limits and nothing persisted: real queries, outputs measured rather than written, and the full log back. Only a save makes a version live, and a version that does not parse cannot be saved at all.
Everything in what follows ran on a live Plexara deployment, the demo environment seeded with a 303-store retail chain, while this article was being written. The automation is the classic one: a morning flash of yesterday’s revenue by region, each region held against its own four-week same-weekday baseline, with the day’s top stores.
The authoring loop
1 · Write, then validate
The assistant writes the script and asks the platform to read it back. Validation parses the source and reports what it would reach, before anything runs.
- capabilities: query · export · publish_data
- refresh targets: regional-flash
- destinations: portal
2 · Dry run, as yourself
A dry run executes the code for real, under the author’s own identity and access, with tighter limits and nothing kept. Real queries, measured outputs, full log.
- status: succeeded · 3 queries · 2.4s
- log: flash for 2025-12-15: 8 regions, 6316 transactions
- nothing persisted; outputs measured, not written
3 · Save, and it runs
The saved version is the version that runs, under the access its author held at the save. Any session can invoke it by name, the portal page runs it with a button, and a schedule fires it unattended.
What the assistant saved
The saved script is ninety-six lines: three SQL queries, arithmetic, and one publish call. Values reach SQL through named placeholders the platform binds by type, never by pasting strings together. The language enforces the rest of the discipline: no network, no filesystem, no clock, no randomness, no unbounded loops. A script touches the world only through governed platform calls, which is what makes its behavior readable before it runs and auditable after.
Nobody on the team has to write this. Somebody on the team gets to read it, and that difference is the control model. The script’s portal page shows the source with syntax highlighting, its version history with each version’s author, and Run, Dry run, and Validate controls beside the editor. An analyst who wants the baseline changed from four weeks to six asks the assistant, or edits the line, and either way the save is refused if it cannot parse and recorded as a new version if it can.
What the assistant saved
acme-regional-flash · version 3 · 96 lines
day = run.params["day"]
base = date.add_days(day, -28)
day_rows = platform.query(
"""SELECT r.region_name, count(*) AS txns, sum(t.total) AS revenue
FROM warehouse.public.transactions t
JOIN warehouse.public.stores s ON s.store_id = t.store_id
JOIN warehouse.public.regions r ON r.region_id = s.region_id
WHERE t.transaction_date >= DATE :day
AND t.transaction_date < date_add('day', 1, DATE :day)
GROUP BY r.region_name""",
connection=conn, params={"day": day},
)["rows"]
platform.publish_data("regional-flash", {
"day": day,
"totals": {"revenue": total_revenue, "txns": total_txns},
"regions": regions,
})Running it: no model, no tokens, under two seconds
Running the saved script is one call, from any session, or the Run button on its portal page. The platform executes it: the queries run in the warehouse, the arithmetic runs in the interpreter, and nothing passes through a model. The interactive session that settled this logic cost an hour of conversation. This run cost three queries and 1.85 seconds, and it charges no tokens against anyone’s AI subscription because no AI was involved.
The run is also a record. Its id, trigger, duration, query count, printed log, and outputs are stored and kept, readable by the script’s owner on the portal page and by the assistant through the same contract. When a scheduled report fails, that record is the difference between a mystery and a fix: the failure reason and the log arrive in the owner’s inbox, and the fix is an edit, a dry run, and a save.
One run, and its record
run_script name=acme-regional-flash args={"day": "2025-12-16"}
- status
- succeeded · trigger: tool · 1.85s
- queries
- 3
- output
- regional-flash → portal · data refresh, 2,067 bytes · asset version 2
- log
- flash for 2025-12-16: 8 regions, 6687 transactions
- run_id
- dpx_a11810b897a4069f4b5a59ad30f512b7
What it produced
The run pushed two kilobytes of JSON into the flash dashboard: $779,390 across 6,687 transactions on December 16, 2025, an average ticket of $116.55, eight regions ranked with their shares, and the day’s five best stores. Every region ran thirty-five to seventy-eight percent ahead of its late-November baseline, which is the demo chain’s holiday surge arriving on schedule, exactly the kind of movement a flash report exists to surface.
The output kept its identity. A run does not create a new file each morning; it writes a new version of the same asset, so the dashboard holds one name, one address, and one share list while its history accumulates underneath. The version from any past run still shows exactly the numbers it showed that day, which makes the history an audit trail as much as an archive.
What the dashboard showed after that run
$779,390
Revenue, December 16, 2025
6,687
Transactions
$116.55
Average ticket
| Region | Share | Revenue | vs 4-wk avg |
|---|---|---|---|
| Midwest | $169,161 | +48.2% | |
| Southeast | $160,347 | +58.2% | |
| Mid-Atlantic | $132,152 | +54.7% | |
| West | $122,192 | +61.5% | |
| Southwest | $101,575 | +35.0% | |
| Northeast | $40,904 | +71.9% | |
| Northwest | $38,576 | +78.2% | |
| Central | $14,484 | +38.7% |
A live dashboard that cannot touch the database
A dashboard that stays fresh usually pays for it with access: a BI tool holding a standing database connection, credentials living in another vendor’s system, and every viewer triggering queries against the warehouse. The security review is about the dashboard’s reach, and the performance question is about what a wall of viewers does to the busy hours.
The flash dashboard inverts the direction of the data. It is a portal document, HTML the assistant wrote once, whose single marked data region holds the numbers as JSON. The scheduled script is the only party that queries: it runs under its author’s access, computes the payload, and pushes it into the region, leaving every other byte of the document untouched. The dashboard itself holds no connection string, no credential, and no ability to ask the warehouse anything.
That split settles both concerns at once. Sharing the dashboard shares numbers, never access, so the audience question and the access question come apart. Load on the warehouse is one run per refresh however many people are watching. And freshness becomes a dial rather than a compromise: schedules fire as often as once a minute, in the timezone you mean, so a floor-wall dashboard can track the morning in near real time while the warehouse sees a few small queries an hour.
The presentation stays editable the whole time, because it is a document. Change a heading or a chart color in the portal and the layout edit survives every scheduled refresh, since the script rewrites only the data region. The seam between the two is checked, not assumed: a refresh against a document whose marked region has gone missing fails loudly rather than writing anywhere else.
The split that removes database access from the dashboard
The dashboard document
- Layout, charts, and headings: edited in the portal like any document
- One marked data region holds the numbers as JSON
- No connection string, no credential, no query anywhere in it
JSON only
The scheduled script
- Queries the warehouse under its author’s own access
- Pushes fresh JSON into the data region on each run
- Every refresh is a new version: an as-of snapshot that keeps
The schedule, and the record it leaves
A schedule is a cadence, a timezone, and the parameter values each fire binds: every weekday at 6:30, Los Angeles time, reporting on the day it fires. The portal asks for it in those words and derives the cron expression itself; a date parameter can bind the fire date, so each run records the day it was computing for and re-running it later asks the same question. Wall clocks hold across daylight-saving changes.
The policies underneath are chosen for reports rather than for pipelines. A fire that arrives while the previous run is still going is recorded as skipped, not silently dropped and not queued into a pileup. After downtime, the platform runs once for the latest missed fire and counts the rest, because a burst of stale reports nobody is waiting for is worse than a visible gap. A failed scheduled run mails its owner with the reason and the log’s tail. And failures are never blindly retried: the same script on the same inputs fails the same way, so the platform records the failure once and waits for the fix.
All of it lands in one place. The portal’s Scripts pages show every automation you own, its schedule in words, its next fire, and how its last run went, with a Failing tile that narrows the list to what needs attention. Runs are kept for a year.


The gap this closes
The interactive assistant and the standing automation have been separate worlds: one reachable by anyone who can hold a conversation, the other gated behind an engineering queue. What closes the gap is letting the conversation produce the automation, on a platform that makes unattended execution safe enough to allow: a script can never do what its author could not, holds no credentials, runs in a language that cannot reach around the platform’s governance, and leaves a complete record of every run.
The economics follow from the split. Judgment stays interactive, where a model earns its cost. Repetition moves to the platform, where a run is three queries and two seconds. The hour you spent getting the report right becomes the last hour that report costs.
