Plan: a command that loads the data, and a command that reports on it
IMPLEMENTATION RULES: Before implementing this plan, read and follow:
- WORKFLOW.md - The implementation process
- PLANS.md - Plan structure and best practices
Status: Backlog — filed 2026-09-10 from imac's novice grading
(urb-agents#506), BLOCKING 5 and 6. Nothing here is a defect in what exists;
it is surface that does not exist.
🔴 This plan was announced before it was written. I told imac on #506 that
these were "filed, not rushed" and that their framing was "in the plan
verbatim", and no plan existed for another twenty minutes. Recorded because it
is the same announced-action-not-taken shape this repository has spent a week
removing, committed in the message reporting on it.
Goal: after uis template install <id> succeeds, a user can load the
application's data and see whether it worked, without knowing Dagster.
Why, in the words of the person who hit it
The install succeeds about two times in three, and when it succeeds the user cannot use the result. Ten minutes of ingest gives a fully working API — 2.9M rows, 13 endpoints — and nothing in the product tells them that is possible.
Atlas installs, answers HTTP 200, and serves zero rows. That is correct behaviour — the schema and grants are the install-time guarantee, the data arrives on the ingest schedule — and it is indistinguishable from a broken install to someone seeing it for the first time.
Phase 1 — uis dagster materialize
🔴 Load-now and keep-fresh are two different operations, and today only the
second exists. That distinction is imac's and it is the thing to get right:
| who wants it | what it does | |
|---|---|---|
./uis dagster materialize --all | someone evaluating the application | loads the data now (~10 min for atlas) |
./uis dagster automation --start | an operator going live | keeps it fresh (weekly Sun 02:00) |
⚠️ --start alone is not a substitute and would strand a novice. Measured:
every automation condition is cron-based — 37 assets on weekly Sunday 02:00
(+63 h), 3 on monthly 1st (+20 days), and 74 of 114 assets carry no condition at
all. transform_daily is +18 h and would transform data not yet fetched. So
enabling the schedules leaves an empty API for 63 hours.
✅ The capability already exists; only the command is missing. imac
launched raw/_migrations through Dagster's GraphQL API and it succeeded in
under 20 seconds, creating the raw and marts schemas and 47 tables.
-
1.1
./uis dagster materialize --all— launch and wait, streaming step progress. Atlas's full load is 10.1 minutes across three jobs -
1.2
--select <asset>for a single asset or group -
1.3
./uis dagster automation --start/--stop. It currently reports0 RUNNING, 4 STOPPEDand cannot change it — its only flag is--expect, an assertion⚠️ **The two mutations return different types and guessing costs a
round.** `startSchedule` returns `ScheduleStateResult`; `startSensor`
> **RESOLVED 2026-09-14 in UIS 1.6.90.** `uis dagster automation
> --start|--stop` exists: it switches every declared schedule and sensor,
> re-reads the state from Dagster, and refuses success on a partial
> change. The paragraph above describes the gap as it stood and is kept
> as the record of why the verb was built — not as a current limitation
> (ops-dev, urb-agents#991, #1057).
returns `Sensor`. Guessing `SensorStateResult` gives a bare HTTP 400 with
nothing in it (atlas, `urb-agents#629`, from a production go-live). That
asymmetry is the reason this verb is worth more than the two-line
workaround it replaces -
1.3b ✅ SHIPPED 1.6.58.
./uis dagster run <job> [--wait]— not the same as 1.1.materializeis asset-shaped; atlas's installer ends by naming four jobs in order, and there is no verb that runs a named job at all. The documented path today is a hand-writtenlaunchPipelineExecutionmutation plus pollingrunOrError, which ops did on a production install and only managed becauseimachad written the shape down inuis-tester. ⚠️ Without this verb the install guide teaches GraphQL, which is where a novice stops (atlas,urb-agents#629) -
1.4 ⚠️
./uis dagsterappears nowhere in the 172-line help.imacfound it by guessing. Whatever else this plan does, that line gets added -
1.4a ✅ SHIPPED 1.6.58. Poll the RUN, not the launch call. ops measured a queue delay of 142.5 s against a 105.1 s runtime on
transform_checks— the wait before the work starts was longer than the work. imac, atlas and ops each called it hung while being early by under two minutes (urb-agents#648). A--waitthat watches the blocking launch call, or that gives up on a fixed short timeout, reproduces that verdict automatically and with the platform's authority behind it -
1.4b ✅ SHIPPED 1.6.58.
--waitreports run state and elapsed time, NOT step counts. atlas measuredtransform_checkslooking hung — 45-second blocking launch, a minute atNOT_STARTED, succeeding in ~105 s — and three people read it as a defect, because all 647 checks run inside one op, sopipelineOrErrorandexecutionPlanOrErrorreturn "1 op, 1 step" instantly and cannot see the weight (atlas,urb-agents#629). Those two are the obvious probes. A--waitbuilt on them would make UIS the fourth reader of a misleading signal, with the platform's authority behind it -
1.5 The install summary should say which of the two a user probably wants
-
1.6 ✅ Done in 1.6.52 —
--dry-runis advertised intemplate list, intemplate infoand in the subcommand help. It pulls the definition and prints the numbered plan without installing anything; ops called it "the clearest description of atlas that exists anywhere" and found it only by reading the install usage line. A capability nobody is told about is one nobody has
Phase 2 — uis template status <id>
The generic form is worth more than an Atlas-specific one, because templates
already declare provides and exports.
Every status-shaped command today reports infrastructure — services, hosts, secrets, tools, platforms, networks. None reports a row, a source or a table, which is the only thing the user came for.
imac's sketch, rendered from one endpoint atlas already publishes
(meta_sources, carrying latest_row_count, total_runs,
downstream_model_count, last_ingested_at):
Atlas — http://api-atlas.localhost/
sources 39 loaded, 2 never run, 41 declared
records 2,906,032 rows
endpoints 91 published
last load 2026-09-10 09:06:23 UTC
never run: frr, redcross-branches
One GET and a print. It answers "is my install healthy" better than
uis status—2 never runis actionable; four green ticks are not.
- 2.1
uis template status <id>reads the application record for itsexports, fetches what the application publishes, and renders it - 2.2 🔴 No hardcoding of Atlas. The application decides what it exposes; UIS renders it. An application that publishes nothing gets a status saying so, not an error
- 2.3 Decide the contract: which export name, and what shape. This is the
one design question in the plan and it is a seam — so it belongs with
atlasanddev-templates, not decided here alone - 2.4 A URL column in
./uis statusfor anything with an IngressRoute, andverifyprinting the address it probed. Both from #506 BLOCKING 4; 1.6.38 did only the install summary
Phase 3 — the non-blocking findings from #506
- 3.1 N1 — when docker is absent UIS prints
docker: command not foundand then advisesdocker build …. Both remedies need the command just reported missing. Say: "Docker was not found on your PATH. If you just installed Rancher Desktop, open a new terminal." ⚠️ Real users hit this:rcfilesonly affects new shells - 3.2 N2/N3 — the first-run Quick Start has no route to installing an
application;
template infosaysKind: applicationwhile the help files it under "Template Deployment"../uis template list Show installable applicationscloses both - 3.3 N9 — the
DAGSTER READYblock answers "where is it" and "how do I log in" and sits at line 682 of 701 as one 929-character line with literal\nescapes inside an Ansible debug envelope. Emit via the launcher's logger after the play, or passmsgas a YAML list - 3.4 F7 — Dagster tasks 11 and 14 are
...ignoringwithno_log: true, so a healthy first install prints two red censoredFAILED!lines and a genuine failure looks identical - 3.5 N5/N6/N7 —
expose --statuslists a service then prints(none); unescaped unicode in the multi-instance error; Dagster's output endsVerify: ./uis verify dagsterfor a verb the help does not document
Acceptance
- a novice installs an application, loads its data and confirms it worked, using only commands the help documents
- 🔴 graded on a machine that has never run UIS — see PLAN-templates-002. The findings this plan comes from were invisible on four clusters that had PostgreSQL and Dagster already installed
Out of scope
- teaching UIS what Atlas's data means.
meta_sourcesis atlas's contract; UIS renders whatever an application publishes - scheduling policy. Whether an application ships with schedules stopped is the
application's decision and
template infoalready states atlas's