Skip to content

Drop synthetic-job / event-stream-bridge framing for 7a-2+#558

Merged
bdraco merged 1 commit into
mainfrom
docs/arch-drop-synthetic-state
May 10, 2026
Merged

Drop synthetic-job / event-stream-bridge framing for 7a-2+#558
bdraco merged 1 commit into
mainfrom
docs/arch-drop-synthetic-state

Conversation

@bdraco
Copy link
Copy Markdown
Member

@bdraco bdraco commented May 10, 2026

What does this implement/fix?

Drops the "synthetic offloader-side FirmwareJob + event-stream
bridge" framing from docs/ARCHITECTURE.md's description of
the transparent install flow's 7a-2 / 7a-3 / 7a-4 slices.
That shape was inherited from the original design doc and
reverse-engineered from "what's the minimum change to avoid
touching the install dialog's subscriber?" — a bad starting
point. It created two FirmwareJobs per remote build (one on
each side), a bridge that re-fired OFFLOADER_JOB_* events as
JOB_* against a synthetic id, and a separate RAM-only id
mapping. Extra ceremony for a problem that doesn't exist —
lockstep frontend deployment means the install dialog can
learn the new field (job.source_label) in the same
coordinated PR that lands the source-routed runner.

What's replacing it

One FirmwareJob per build, the runner branches on
source to pick its pipeline (local subprocess vs peer-link
submit_job dispatch). Same JOB_* lifecycle events fire
either way; the install dialog stays on its existing
subscriber. OFFLOADER_JOB_* events remain as the wire-layer
fan-out (5c-3 keeps them for the explicit Send-builds dialog
that hangs around as the power-user surface); the runner
consumes them privately to update its single FirmwareJob.

Renumbered slices to reflect the new shape:

  • 7a-2a: FirmwareJob.source / source_pin_sha256 /
    source_label field additions. In flight as Add FirmwareJob.source / source_label fields (7a-2a) #556.
  • 7a-2b: source-routed runner (renamed from
    "event-stream bridge"; the bridge concept disappears
    entirely). The firmware queue's _run_job gains a branch on
    job.source; LOCAL keeps the existing esphome run
    subprocess; REMOTE calls PeerLinkClient.submit_job and
    subscribes to OFFLOADER_JOB_* filtered to its dispatch's
    job_id, updating the same FirmwareJob's status as wire
    events arrive.
  • 7a-3: firmware/install integration. Unchanged in
    spirit but now constructs a regular FirmwareJob with
    source=REMOTE rather than a synthetic wrapper.
  • 7a-4: cancel translation. Simplifies — the runner's
    cancel hook fires remote_build/cancel_job directly. No
    id translation between two FirmwareJobs because there
    aren't two.

Added a leading paragraph above the slices that explains why
the synthetic framing was wrong, so future readers don't have
to reconstruct the reasoning from PR history.

Related coordinated changes

Related issue or feature:

Types of changes

  • Bugfix (non-breaking change which fixes an issue) — bugfix
  • New feature (non-breaking change which adds functionality) — new-feature
  • Enhancement to an existing feature — enhancement
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) — breaking-change
  • Refactor (no behaviour change) — refactor
  • Documentation only — docs
  • Maintenance / chore — maintenance
  • CI / workflow change — ci
  • Dependencies bump — dependencies

Frontend coordination

  • No frontend change needed
  • Companion frontend PR: esphome/device-builder-dashboard-frontend#

Checklist

  • The code change is tested and works locally.
  • Pre-commit hooks pass (ruff, codespell, yaml/json/python checks).
  • Tests have been added or updated under tests/ where applicable — N/A; docs-only.
  • components.json has not been hand-edited.
  • Architecture-level changes are reflected in docs/ARCHITECTURE.md and/or docs/API.md — this PR is the architecture-level reflection.

Copilot AI review requested due to automatic review settings May 10, 2026 23:22
@github-actions github-actions Bot added the docs Documentation label May 10, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 10, 2026

Merging this PR will not alter performance

✅ 12 untouched benchmarks


Comparing docs/arch-drop-synthetic-state (f58fe49) with main (ca1ce69)

Open in CodSpeed

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.12%. Comparing base (ffb8274) to head (e45b810).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #558   +/-   ##
=======================================
  Coverage   99.12%   99.12%           
=======================================
  Files          77       77           
  Lines       10033    10033           
=======================================
  Hits         9945     9945           
  Misses         88       88           
Flag Coverage Δ
py3.12 99.09% <ø> (ø)
py3.14 99.12% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the transparent install flow architecture documentation to remove the “synthetic FirmwareJob + event-stream bridge” framing and describe the newer “one FirmwareJob per build, source-routed runner” model for slices 7a-2+.

Changes:

  • Adds rationale explaining why the synthetic-job / event-translation bridge approach was unnecessary.
  • Renumbers and rewrites the in-flight slices as 7a-2a / 7a-2b / 7a-3 / 7a-4 to match the first-class FirmwareJob.source shape.
  • Updates the described event flow so OFFLOADER_JOB_* stays as wire fan-out, while the runner privately consumes it and continues emitting JOB_* for the install dialog.

Comment thread docs/ARCHITECTURE.md Outdated
The arch.md description of the transparent install flow's
implementation slices used a "synthetic offloader-side
FirmwareJob + event-stream bridge" framing inherited from the
original design doc. That shape was reverse-engineered from
"what's the minimum change to avoid touching the install
dialog's subscriber?" — a bad starting point. It created two
FirmwareJobs per remote build (one on each side), a bridge
that re-fired OFFLOADER_JOB_* events as JOB_* against a
synthetic id, and a separate RAM-only id mapping. Extra
ceremony for a problem that doesn't exist: lockstep frontend
deployment means the install dialog can learn the new field
(`job.source_label`) in the same coordinated PR that lands the
source-routed runner.

Replaced the 7a-2 / 7a-3 / 7a-4 section with the first-class
shape:

- One `FirmwareJob` per build, the runner branches on `source`
  to pick its pipeline (local subprocess vs peer-link
  `submit_job` dispatch).
- Same `JOB_*` lifecycle events fire either way; the install
  dialog stays on its existing subscriber.
- `OFFLOADER_JOB_*` events stay as the wire-layer fan-out
  (5c-3 keeps them for the explicit Send-builds dialog that
  hangs around as the power-user surface); the runner
  consumes them privately to update its single FirmwareJob.

Renumbered slices to reflect the new shape:

- 7a-2a: `FirmwareJob.source` / `source_pin_sha256` /
  `source_label` field additions (in flight as #556).
- 7a-2b: source-routed runner (renamed from "event-stream
  bridge"; the bridge concept disappears entirely).
- 7a-3: `firmware/install` integration unchanged in spirit
  but now constructs a regular FirmwareJob with source=REMOTE
  rather than a synthetic wrapper.
- 7a-4: cancel translation also simplifies — the runner's
  cancel hook fires remote_build/cancel_job directly, no id
  translation between two FirmwareJobs.

Added explanatory paragraph above the slices about why the
synthetic framing was wrong, so future readers don't have to
reconstruct the reasoning from PR history. Issue #106's
§ Transparent install flow gets the same drop in a separate
edit (the issue body is the source of truth for the full
design; this PR brings arch.md into alignment).

No code change.
@bdraco bdraco force-pushed the docs/arch-drop-synthetic-state branch from 84fa1a1 to f58fe49 Compare May 10, 2026 23:29
@bdraco bdraco merged commit 2c97a87 into main May 10, 2026
8 of 11 checks passed
@bdraco bdraco deleted the docs/arch-drop-synthetic-state branch May 10, 2026 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants