Files
open-design/apps
d4e1b47024 fix(web): remove the "use the system automatic scenario" header entry (#7505)
* fix(web): stop offering to restore a scenario the project never left

Every first-level output type on Home's create rail is a product-owned
automatic scenario: the user picks a task type, never a plugin. Such a
create has to travel as `pluginSelectionProvenance: 'automatic-default'`
so `EntryShell` omits `pluginId` and `POST /api/projects` re-derives the
plugin from the metadata and stamps an `automatic_default` binding.

Only Prototype, Slide deck and HyperFrames carried `automaticDefault`.
The other seven — Image, Video, Audio, Document, Website clone, Live
artifact, WebGL — forwarded their scenario plugin id instead. Naming a
plugin is real authority on the daemon side (it is how a caller opts a
project out of OD Next), so those projects were created with no
automatic scenario binding at all, `hasCurrentAutomaticScenarioBinding`
returned false, and the project header offered "use the system automatic
scenario" on a project sitting on its default. `runs.ts` recomputed the
same judgement per run and labelled them `explicit_user`.

Mark the remaining seven. That leaves the daemon's rule untouched: a
body that names a plugin still means what it has always meant.

WebGL needs one more row to be able to claim it. Its card binds
`example-webgl-experience`, but `defaultScenarioPluginIdForProjectMetadata`
did not map `intent: 'webgl-experience'` and resolved to the generic
`example-web-prototype` seed — so dropping the plugin id would have bound
the wrong plugin. Map the intent, alongside the `web-clone`,
`live-artifact` and `hyperframes` cards it is shaped like.

`automaticDefault` was never the OD Next gate — that is decided by chip
id through `automaticStrategyTaskProfileForRouteId`, and the daemon
re-derives it from metadata besides. Two rail assertions used the flag as
a proxy for "owns no OD Next route"; point them at the real gate.

* fix(web): read the running scenario, not the label its create stamped

Marking the seven cards fixes the create they own, but the header entry is
decided per project, not per create surface. It still appeared on a pick made
UNDER one of those cards — a preset/example card, a plugin card's 「使用」 —
because those set `explicitPick`, and `pinsPluginOverAutomaticRoute` degrades to
exactly that flag for any card owning no OD Next route (`examplePickReference`
returns null there), so the plugin id travels again. It also still appeared on
every project that already exists, which the migration stamps `legacy_unknown`.

`hasCurrentAutomaticScenarioBinding` asked whether the recorded provenance is
`automatic_default`. That is a different question from the one the entry
answers. A body that names a plugin is recorded `explicit_user`, and rightly
so — naming a plugin is how a caller opts a project out of OD Next — but it says
nothing about WHICH scenario is running, so it cannot by itself mean the project
left one.

Ask the question the entry actually answers. `projectLeftItsAutomaticScenario`
compares the running scenario with the one the automatic router would pick, per
shape of "automatic":

  - metadata that owns an OD Next route: the automatic scenario is that strategy
    route, which pins no scenario plugin, so any pinned snapshot is a departure
    and restoring hands the task back to OD Next;
  - everything else: the automatic scenario is the metadata's default plugin, so
    a project already bound to it has nothing to restore.

Decided from the project row, so it covers every create path and every project
that already exists. The daemon's routing authority is untouched: those creates
stay `explicit_user` and OD Next still declines them.

Fold the two restore-entry suites into one under `tests/routes/`, next to the
other `/api/projects` boundary tests. It now runs both shapes each card can
reach the create with — the card's own automatic default, and a pick under it
that forwards the scenario plugin — and both must leave the header alone.

* fix(web): remove the "use the system automatic scenario" header entry

The entry is three weeks old — it arrived with the OD Next rollout controls
in f638492 — and every report since has been about it appearing where it does
not belong. Three rounds of narrowing the condition each left another way in:
the seven task-type cards that forward their plugin id, then a preset/example
card under any of them (`explicitPick` makes `pinsPluginOverAutomaticRoute`
true for every card owning no OD Next route), then every project created
before the feature existed, which the migration stamps `legacy_unknown`.

Chasing the create surfaces was the wrong shape. Off the OD Next routes there
is no strategy to return to: the "automatic scenario" is only the metadata's
generic default plugin, and every way a project leaves it — an example card
under its own task type, a Community pick, the plugin detail modal — supplies
the material the artifact is made of. A header button that swaps that for the
generic seed reads as a routing control and behaves like a discard. On the OD
Next routes the affordance is real but has never been asked for from the
header.

So drop the entry rather than keep qualifying it: the Button, its confirm /
busy states, the `restoreProjectAutomaticScenario` client, the four i18n keys
across all 19 locales, its CSS module, and the two contracts predicates that
existed only to answer it.

The capability itself is untouched. `POST /api/projects/:id/scenario/restore-automatic`
and `od project restore-automatic-scenario` still serve both shapes for a
caller that asks for it by name, and `od-next-automatic-simple-server` still
covers restoring an explicitly pinned project back onto its strategy route.

What stays from the create-rail half is the part that was never about the
button: the seven cards now claim their product-owned automatic default, so
`routes/runs.ts` stops recomputing them as `explicit_user` when nobody pinned
anything. Its daemon-boundary suite is renamed to what it actually pins now —
the provenance each create records — with the header-gate assertions dropped.

---------

Co-authored-by: Cheems <94773058+itscheems@users.noreply.github.com>
2026-08-28 04:30:48 +00:00
..