Harness: the preview pane says only "Hugo wird gestartet…" for the whole first build, and Hugo starts after the startup sync #362
Labels
No labels
bug
enhancement
needs-triage
ready-for-agent
ready-for-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/deckle#362
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The preview pane says nothing but "Starting Hugo…" for the whole first build,
which on a 2,573-page site is 2.5 minutes, so people reload a harness that is
working. Show what is happening — elapsed time, site size, Hugo's own output —
make the elapsed time survive a reload via the status API, and start Hugo
before the startup sync instead of after it.
Current behavior
PreviewPane's fallback branch (state neitherrunningnorcrashed)renders the
preview.startingstring and nothing else, although the panealready receives
outputand the status store already polls it.GET /api/statuscarries no start time; the supervisor records none. Areload (on hosted: a re-poll of the wake) starts the user's clock at zero.
cmd/harness serverunsstartupSyncto completion beforesupervisor.Start, so in branch mode Hugo launches only after the sync'scommit, fetch, reset, collapse and push (about 10 s on gbv-aktuell).
Confirmed by reading the code; the timings are from the hosted journal in the
original report below.
Desired behavior
The placeholder is a centered state, not a word. While the state is
startingthe pane shows, centered:formatted for reading ("12 s", "2 min 05 s"), never negative;
until then;
build of a site takes a while and the page stays usable afterwards (wording
in both
en.jsonandde.json);outputin the same monospace block the crash paneluses, scrolled to the last line, so Hugo's "Start building sites" and any
ERROR lines are visible while it works.
The same placeholder serves a restart after a crash (the state returns to
starting): the clock then counts that run.The status API says when the run started.
GET /api/statusgainsstartedAt: RFC3339, the time the current Hugo process was launched;""before the first launch. It is set per run, so a restart resets it, and it
stays set while
running(its age is harmless there). The client computesthe elapsed time from it and clamps a negative difference (clock skew) to 0.
Hugo starts before the sync. In
serve, the supervisor starts beforestartupSync; the listener still comes after the sync, as today, so nothingelse about the startup order changes. A sync that moves the checkout is
picked up by Hugo's watcher as a change (see Decisions), so no restart logic
is needed.
Decisions
report's condition ("only when the checkout is in sync") cannot be known
before the sync runs, and it is not needed: Hugo 0.161.1 creates its file
watcher before the first build (
commands/server.go,Run:newWatcherthen
build), so areset --hardduring the build queues a rebuild ratherthan being lost — the same path a
POST /api/git/syncon a running editortakes. The listener stays after the sync so the editor never serves a
moving checkout. Accepted cost: a transient build error if Hugo reads a
file mid-reset, cleared by the queued rebuild.
avoids a "large site" threshold rule that nobody owns; the page count is
shown as a fact whenever the tree is loaded.
GET /api/statustakes no lock and does no content or git work (ADR 0030)and must stay that way; the tree poll already delivers every node, and "a
node with
path === ""is synthesized, not a page" is an existing wire fact(
docs/api.mdGET /api/tree) the client already applies. Count thedefault-language tree's nodes with a non-empty
path.startedAtis a time, not a duration. It lets the hosted dashboardshow the same clock later. Skew is handled by clamping.
state" (
.center,.center__box,.center__markincomponents.css),whose description already names "starting"; the output tail reuses the
crash panel's output block (one class for both). No new colour, token,
component or styleguide sample.
Key interfaces
supervisor.Status— gainsStartedAt time.Time, set undermuwhenrunOncelaunches the child; zero before the first launch. Starting hint:internal/supervisor/supervisor.go.GET /api/statusresponsehugo.startedAt: string— RFC3339 or"";statusResponse/hugoStatusininternal/server;HugoStatusand thestore in
web/src/api/status.tsandweb/src/stores/hugoStatus.ts(onemore per-field signal, so unchanged values do not notify).
PreviewPaneprops — receives the start time and a page count accessor(from the page tree store the module context already holds; the pane is
mounted in
web/src/modules.tsx).cmd/harness serve—sup.Startmoves ahead ofstartupSync; theensureMediaRootcall must still precedesup.Start(Hugo mounts themedia directory). Starting hint:
cmd/harness/main.go,reconcile.go.web/src/i18n/en.jsonandde.json(the parity testenforces both); the elapsed-time format and the
{count}plural use theexisting interpolation.
Acceptance criteria
starting, the preview pane shows the heading, a tickingelapsed time, the page count once the tree is loaded, and the tail of
outputin a scrolling monospace block.after, in English and German.
startedAt, not from zero; astartedAtin the future reads as 0 s.GET /api/statusreturnsstartedAtas RFC3339 once Hugo was launchedand
""before; a restart after a crash gives a newer value.servelaunches Hugo before the startup sync andlistens after it; stderr still logs the sync result. In WIP mode
nothing observable changes.
preview with no manual restart (integration test with a fake remote
and a slow-building fixture, or a supervisor test that proves a file
change during the first build is followed by "Change detected").
docs/api.mdGET /api/status documentsstartedAt;docs/harness.md"Serving" and
docs/architecture.md"Branch mode" state the new order.web/src/styles.csspasses its styleguide test; the preview pane uses
.centerand theshared output block.
How to verify
go test ./...(supervisor, server route/doc tests,cmd/harnessserve and reconcile tests,
docs/drift tests) andcd web && npm test(PreviewPane tests, i18n parity, styles test).
harness serveon the scaffold site and reload the editor duringthe first build on a large fixture (a copy of the scaffold with a few
thousand generated pages) — the clock, the count and the output tail
appear; the clock survives the reload.
Hugo logs "Start building sites" before the stderr "startup sync" line,
then "Change detected" and a successful rebuild.
Assumptions to check
build,
commands/server.goRun). Confirm the pin and the ordering forthe version the scaffold ships; if a version builds before watching, the
harness must restart Hugo when
SyncResult.Changedis true instead.changed config without a restart; a config change triggers Hugo's own
full reload.
module context the preview pane is rendered from.
Out of scope
#163); this issue only supplies
startedAt.reads the new field, and the local startup order it describes (WIP mode)
is unchanged.
Blocked by
None - can start immediately
Original report
What happens
On gbv-aktuell (2,573 pages) the first Hugo build takes 2.5 minutes in the hosted instance (deckle-hosted #163). For all of it
PreviewPaneshows the placeholderpreview.startingand nothing else: no elapsed time, no hint that a large site takes minutes, none of Hugo's output although the supervisor holds its last 200 lines inStatus.Output. Users read it as hung and reload, which on hosted re-polls the wake and changes nothing.cmd/harness/main.goalso runsstartupSyncto completion beforesup.Start, so on this site Hugo starts 10 s after the container does. The sync's reset can move the checkout, so starting Hugo first would risk a second full build; but the sync's git work and Hugo's config and content read could overlap for the common in-sync case, or the supervisor could start with the build paused until the sync reports.Fix
statewas first seen asstarting, the site's page count (the tree poll has it), and a line such as "The first build of a site this size takes a few minutes"; below it the tail ofoutputas the crash panel already shows it, so Hugo's own "Start building sites" and its error lines are visible while it works.GET /api/statusgainsstartedAt(when the current Hugo run started) so the elapsed time survives a reload and the hosted dashboard can show it too.Evidence
Journal of
deckle-instance-gbv-aktuellon 2026-10-31:deckle harness listening18:37:44,site preview ready18:40:07; the earlier start 15:50:17 to 15:55:37.web/src/components/PreviewPane.tsxMatch when={true}branch;internal/supervisorStatus.Output.