Skip to content

Offer builder's FPV stacks in the installer, and let /low-latency install them (#390) - #404

Merged
openipc-ai merged 2 commits into
masterfrom
fpv-editions-390
Oct 7, 2026
Merged

openipc-ai merged 2 commits into
masterfrom
fpv-editions-390

Conversation

@openipc-ai

Copy link
Copy Markdown
Collaborator

Refs #390.

RubyFPV, wfb-ng (fpv) and apfpv are built in OpenIPC/builder, not firmware, and the site offered none of them. LoadIndex read only source IN ('firmware','uboot'), and full images were fetched only from firmware's releases. Builder's tarballs have firmware's layout (uImage.<soc>, rootfs.squashfs.<soc>; checked on openipc.ssc338q-nor-fpv.tgz and ssc338q_rubyfpv_generic-nor.tgz), so the assembler takes them unchanged.

Service

  • Index: builder's generic builds of the FPV editions (wfbng, fpv, waybeam, rubyfpv, apfpv) are indexed under the name firmware would give them.
    • ssc338q_rubyfpv_generic-nor.tgz becomes openipc.ssc338q-nor-rubyfpv.tgz. The asset keeps its real file name and repo.
    • Firmware wins a name both publish. Device builds and builder's own non-FPV variants stay out.
  • Rename window: wfbng is offered over fpv once builder publishes both (the planned builder rename).
  • Fetch: builder assets come from BUILDER_DOWNLOAD_BASE (default https://github.com/OpenIPC/builder/releases/download).
  • Fits come from builder's size reports (board/variant/flash_mb). A builder edition with no report is not taken for an 8 MB build.
  • Wizard: builder editions come after lite/ultimate/neo. Links go to builder's release under the published file name.
  • /api/v1/hardware/availability.json gains an additive fpv map: the FPV editions each installable SoC has.

Site

  • Edition labels in en/ru/zh: wfb-ng (FPV), Waybeam (FPV), RubyFPV, APFPV (Wi-Fi AP). The wizard result notes that the image comes from OpenIPC/builder, and that sysupgrade updates it from there.
  • /low-latency: the build cards become four (wfb-ng, Waybeam, RubyFPV, apfpv). Each has its project link and "Install on" buttons for the SoCs it is published for.
    • The buttons open the installer at ?rom=nor16m&ver=<edition>. These are 16 MB images, and on an 8 MB chip the wizard would turn the edition into Lite; there is a test for this.
    • The SoC lists are prerendered from today's state and corrected on load from the feed. Waybeam reads "not built yet" until builder ships it.
    • Clicks are lowlat:try:<stack>:<soc>. lowlat:offer is untouched.
  • The Waybeam link now points at OpenIPC/waybeam (renamed from waybeam_venc).

Also

  • Removes service/deploytest/noruby_test.go. No Ruby is left to guard against, and it tripped on RubyFPV.

Tests

  • service/run.sh test, bin/conformance, frontend lint / typecheck / test / build all pass locally.
  • New tests:
    • firmware/builder_test.go: name mapping, wfbng over fpv, fetch from builder under the upstream name, the fpv feed.
    • builds: TestLoadIndexBuilderEditions (DB).
    • wizard: TestBuilderEditions.
    • Frontend: editions.test.ts, plus the link-opening cases in wizard-menu.test.ts.

Validation on dev before prod

  • /api/v1/wizard/ssc338q.json lists fpv, rubyfpv and apfpv under nor.
  • A download_full_image?...&fw_release=rubyfpv image's kernel and rootfs md5 match the tarball's .md5sum files.
  • /low-latency "RubyFPV → SSC338Q" opens the installer with RubyFPV selected.

Follow-ups, from the same plan:

  • firmware: accept wfbng where fpv is tested, and sysupgrade fpv→wfbng.
  • majestic-webui: updatewebui.
  • builder: rename fpv → wfbng, with old names aliased for cameras in the field.
  • builder: an ssc338q_waybeam profile.
  • builder: why gk7205v200_rubyfpv_generic publishes no tarball.

…tall them (#390)

RubyFPV, wfb-ng and apfpv are built in OpenIPC/builder, and the site
offered none of them: the firmware index read only firmware and u-boot
builds, and full images were fetched only from firmware's releases.

- The index takes builder's generic builds of the FPV editions (wfbng,
  fpv, waybeam, rubyfpv, apfpv) under the names firmware would give them.
  <soc>_<variant>_generic-<storage>.tgz, how builder publishes RubyFPV,
  maps to its edition, and the asset remembers the file and the repo it
  downloads from (BUILDER_DOWNLOAD_BASE). Firmware wins a name both
  publish, and wfbng is offered over fpv while builder carries both.
- Fits come from builder's size reports. A builder edition with none is
  not taken for an 8 MB build.
- The wizard orders them after firmware's editions and links them to
  builder's release under the file name builder published. The result
  says the image comes from OpenIPC/builder.
- /api/v1/hardware/availability.json gains `fpv`: the FPV editions each
  installable SoC has.
- /low-latency's build cards become four (wfb-ng, Waybeam, RubyFPV,
  apfpv), each with its project link and the SoCs it installs on,
  linked into the installer with the 16 MB chip and the edition chosen,
  and corrected on load from the feed. Clicks are lowlat:try:<stack>:<soc>.

Also drops service/deploytest/noruby_test.go: no Ruby is left to guard
against, and it was tripping on the stack's name.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Offer builder FPV editions in the installer and on /low-latency

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Index builder’s FPV editions and fetch their images from builder releases.
• Offer installable editions in the wizard and link supported SoCs from /low-latency.
• Add availability data, localized guidance, and tests for naming, downloads, and flash-size safety.
Diagram

graph TD
  Builder["Builder releases"] --> DB[("Build records")] --> Index["Firmware index"] --> Feed["Availability API"] --> Page["Low-latency page"] --> Wizard["Installer wizard"] --> Images["Image assembler"]
  Index --> Wizard
  Index --> Images
  Images --> Builder
Loading
High-Level Assessment

Extending the existing build index is the best fit: it preserves the established asset cache, firmware-name precedence, and size-report workflow. Reading GitHub releases directly from the page or wizard would duplicate availability logic and bypass those safeguards.

Files changed (32) +813 / -71

Enhancement (10) +384 / -25
LowLatency.astroLink FPV build cards into the installer +84/-9

Link FPV build cards into the installer

• Renders four stack cards with project links and 16 MB installer links. Refreshes their SoC lists from the live FPV availability feed.

frontend/apps/site/src/components/pages/LowLatency.astro

Result.tsxIdentify builder editions in flashing instructions +4/-0

Identify builder editions in flashing instructions

• Shows a localized builder and sysupgrade notice when the selected firmware edition comes from builder.

frontend/apps/site/src/components/wizard/Result.tsx

fpv-stacks.tsDefine FPV stacks and initial SoC availability +52/-0

Define FPV stacks and initial SoC availability

• Defines the four cards, their upstream links, and prerendered SoC-to-edition mappings. Keeps both wfb-ng names in preference order.

frontend/apps/site/src/data/fpv-stacks.ts

editions.tsIdentify builder-owned FPV editions +12/-0

Identify builder-owned FPV editions

• Defines the five accepted edition names and a helper for showing builder-specific installation guidance.

frontend/apps/site/src/lib/editions.ts

platforms.tsOrder new FPV variants in the explorer +1/-1

Order new FPV variants in the explorer

• Places wfbng and waybeam alongside the existing FPV variants in generic-variant display order.

frontend/apps/site/src/lib/explorer/platforms.ts

source.goImport generic builder FPV releases and fits +98/-1

Import generic builder FPV releases and fits

• Adds eligible builder tarballs under firmware-style index names while retaining their published filenames and release metadata. Loads builder size reports and gives firmware assets precedence on name collisions.

service/internal/builds/source.go

availability.goExpose installable FPV editions by SoC +38/-3

Expose installable FPV editions by SoC

• Adds an fpv map to the availability response, listing indexed FPV editions for SoCs with a published bootloader.

service/internal/firmware/availability.go

fetch.goFetch builder assets from their own releases +9/-2

Fetch builder assets from their own releases

• Selects the builder download base for builder assets and requests each asset under its published filename.

service/internal/firmware/fetch.go

index.goTrack builder provenance and normalize FPV names +62/-3

Track builder provenance and normalize FPV names

• Adds repository and upstream-filename metadata to assets, recognizes eligible generic builder editions, and suppresses fpv when wfbng is also offered. Includes the new metadata in index fingerprints.

service/internal/firmware/index.go

export.goOffer builder editions with correct links and flash fits +24/-6

Offer builder editions with correct links and flash fits

• Orders FPV editions after firmware editions and emits builder release URLs and published filenames. Prevents a builder edition without a size report from being assumed to fit 8 MB NOR.

service/internal/wizard/export.go

Tests (7) +320 / -3
editions.test.tsTest FPV edition and card consistency +44/-0

Test FPV edition and card consistency

• Checks the builder-edition list against the stack definitions, validates initial SoC slugs, and tests wfb-ng preference and English labels.

frontend/apps/site/src/lib/editions.test.ts

wizard-menu.test.tsTest edition selection from 16 MB links +18/-0

Test edition selection from 16 MB links

• Verifies that a builder edition survives selection on a 16 MB NOR chip but falls back to Lite on an 8 MB chip.

frontend/apps/site/src/lib/wizard-menu.test.ts

reports_test.goDecouple report guard from removed test +2/-1

Decouple report guard from removed test

• Uses strconv.Itoa instead of the helper formerly supplied by the deleted deploy test.

service/deploytest/reports_test.go

builds_test.goTest builder assets entering the index +68/-0

Test builder assets entering the index

• Exercises generic-name mapping, firmware precedence, exclusion of device and non-FPV builds, and imported size-report fits.

service/internal/builds/builds_test.go

availability_test.goUpdate availability response reference +2/-2

Update availability response reference

• Accounts for the additive, empty fpv map in the reference response.

service/internal/firmware/availability_test.go

builder_test.goTest builder naming, fetching, and availability +124/-0

Test builder naming, fetching, and availability

• Covers accepted and rejected builder filenames, wfbng-over-fpv presentation, downloads under upstream names, and bootloader-gated FPV availability.

service/internal/firmware/builder_test.go

wizard_test.goTest builder editions in wizard documents +62/-0

Test builder editions in wizard documents

• Checks edition ordering, builder URLs and filenames, and exclusion from 8 MB combinations with or without a size report.

service/internal/wizard/wizard_test.go

Documentation (13) +106 / -42
CLAUDE.mdRemove obsolete deploy-test guidance +1/-3

Remove obsolete deploy-test guidance

• Replaces the description of the retired-stack guard test with a pointer to its history after that test’s removal.

CLAUDE.md

en.ymlAdd English FPV wizard labels +6/-0

Add English FPV wizard labels

• Adds builder-source guidance and names for the FPV editions.

data/locales/en.yml

pages.en.ymlDescribe four installable stacks in English +11/-6

Describe four installable stacks in English

• Adds Waybeam and installation-card text, revises the stack descriptions, and points the Waybeam link to its renamed repository.

data/locales/pages.en.yml

pages.ru.ymlDescribe four installable stacks in Russian +11/-6

Describe four installable stacks in Russian

• Localizes the new installation cards and Waybeam description, and corrects the project link.

data/locales/pages.ru.yml

pages.zh.ymlDescribe four installable stacks in Chinese +11/-6

Describe four installable stacks in Chinese

• Localizes the new installation cards and Waybeam description, and corrects the project link.

data/locales/pages.zh.yml

ru.ymlAdd Russian FPV wizard labels +6/-0

Add Russian FPV wizard labels

• Adds builder-source guidance and localized names for the FPV editions.

data/locales/ru.yml

zh.ymlAdd Chinese FPV wizard labels +6/-0

Add Chinese FPV wizard labels

• Adds builder-source guidance and localized names for the FPV editions.

data/locales/zh.yml

en.jsonSync English low-latency page strings +11/-6

Sync English low-latency page strings

• Adds generated strings for the four installable cards and updates the Waybeam repository link.

frontend/apps/site/src/i18n/en.json

ru.jsonSync Russian low-latency page strings +11/-6

Sync Russian low-latency page strings

• Adds generated strings for the four installable cards and updates the Waybeam repository link.

frontend/apps/site/src/i18n/ru.json

wizard.en.jsonSync English builder-edition wizard strings +7/-1

Sync English builder-edition wizard strings

• Adds generated edition labels and the builder-source notice.

frontend/apps/site/src/i18n/wizard.en.json

wizard.ru.jsonSync Russian builder-edition wizard strings +7/-1

Sync Russian builder-edition wizard strings

• Adds generated edition labels and the builder-source notice.

frontend/apps/site/src/i18n/wizard.ru.json

wizard.zh.jsonSync Chinese builder-edition wizard strings +7/-1

Sync Chinese builder-edition wizard strings

• Adds generated edition labels and the builder-source notice.

frontend/apps/site/src/i18n/wizard.zh.json

zh.jsonSync Chinese low-latency page strings +11/-6

Sync Chinese low-latency page strings

• Adds generated strings for the four installable cards and updates the Waybeam repository link.

frontend/apps/site/src/i18n/zh.json

Other (2) +3 / -1
main.goWire builder downloads into the firmware role +1/-1

Wire builder downloads into the firmware role

• Passes the configured builder release base to the release fetcher.

service/cmd/openipc/main.go

config.goConfigure the builder release endpoint +2/-0

Configure the builder release endpoint

• Adds BUILDER_DOWNLOAD_BASE with the OpenIPC/builder GitHub releases URL as its default.

service/internal/config/config.go

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. NAND-only builds appear on 8 MB NOR ✓ Resolved
Description
fitsEight returns true when an edition has no size report and no NOR asset, even if its builder
asset exists only for NAND. When NOR has no published releases, editionsFor falls back to editions
published for other flash types and includes that edition in 8 MB NOR combinations.
Code

service/internal/wizard/export.go[R229-230]

+		a, held := e.idx.Asset(e.linuxFilename(edition, "nor"))
+		return !held || a.Repo != firmware.RepoBuilder
Evidence
The new fallback in fitsEight treats an absent NOR asset as a fit. The wizard's existing fallback
menu can draw an edition from NAND releases and uses fitsEight to decide whether to include it in
an 8 MB NOR combination.

CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit: CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit: CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit: CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit
service/internal/wizard/export.go[224-232]
service/internal/wizard/export.go[159-181]
service/internal/wizard/export.go[302-333]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A builder edition published only for NAND can enter an 8 MB NOR combination without a NOR image or supporting size report.
## Fix Focus Areas
- service/internal/wizard/export.go[224-232]
- service/internal/wizard/export.go[302-333]
## Recommended Fix
Require a published NOR asset and a qualifying size report before admitting a builder edition to an 8 MB NOR combination, including the fallback menu.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Old images inherit unrelated size reports 📘 Rule violation ≡ Correctness
Description
LoadIndex selects builder size reports by board and variant without matching them to the build
that supplied each indexed tarball. A newer 8 MB report can make an older retained image eligible
for 8 MB combinations, while an older report can make a newer tarball with no usable report eligible
despite the no-report safeguard.
Code

service/internal/builds/source.go[R111-117]

+		SELECT DISTINCT ON (r.board, r.variant) r.board, r.variant, r.flash_mb,
+			coalesce(r.kernel_used_kb, 0), coalesce(r.rootfs_used_kb, 0)
+		FROM platform_reports r JOIN builds b ON b.id = r.build_id
+		WHERE b.source = 'builder' AND r.flash_mb IS NOT NULL
+		  AND r.variant = ANY($1)
+		  AND (r.platform = r.board || '-' || r.variant OR r.platform = r.board || '_' || r.variant || '_generic')
+		ORDER BY r.board, r.variant, b.built_at DESC, b.id DESC`, firmware.FPVEditions)
Evidence
The asset query selects the newest retained tarball per filename, while the report query
independently selects the newest matching report per board and variant; neither query requires their
build IDs to match. Because builder pushes can store assets and reports independently, the wizard
can use a fit from another build when deciding whether to offer an 8 MB layout.

CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit: CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit: CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit: CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit
service/internal/builds/source.go[110-129]
service/internal/builds/source.go[140-176]
service/internal/wizard/export.go[224-232]
service/internal/builds/source.go[110-130]
service/internal/builds/store.go[55-83]
service/internal/wizard/export.go[218-232]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Builder size reports can describe a different build from the tarball retained in the index, allowing an unrelated report to establish an 8 MB fit.
## Fix Focus Areas
- service/internal/builds/source.go[110-130]
- service/internal/builds/source.go[140-185]
## Recommended Fix
Associate each builder edition's fit with the build that supplied its selected tarball. Do not use a report from another build; when the selected build has no usable matching report, leave its fit absent so the existing builder no-report rule excludes it from 8 MB layouts. Add a test with an older reported build and a newer unreported tarball.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Missing sizes pass as 8 MB fits ✓ Resolved
Description
The builder-report query converts missing kernel or rootfs usage to zero before storing the fit.
When a report has flash_mb=8 but omits either measurement, it passes fitsEight and reaches 8 MB
wizard combinations without confirming that both partitions fit.
Code

service/internal/builds/source.go[R111-113]

+		SELECT DISTINCT ON (r.board, r.variant) r.board, r.variant, r.flash_mb,
+			coalesce(r.kernel_used_kb, 0), coalesce(r.rootfs_used_kb, 0)
+		FROM platform_reports r JOIN builds b ON b.id = r.build_id
Evidence
Builder size-report usage fields are optional, and pushes preserve omitted values as SQL NULL. The
added query converts those NULL values to zero, which the wizard compares against its positive 8 MB
partition limits, accepting an unverified fit.

CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit: CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit: CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit: CLAUDE.md: Offer 8 MB Wizard Images Only When They Fit
service/internal/builds/payload.go[46-66]
service/internal/builds/source.go[110-129]
service/internal/wizard/export.go[224-232]
service/internal/builds/store.go[100-113]
service/internal/wizard/export.go[218-232]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Missing builder kernel or rootfs measurements are interpreted as zero, allowing an unverified report to qualify for an 8 MB layout.
## Fix Focus Areas
- service/internal/builds/source.go[110-130]
- service/internal/wizard/export.go[224-232]
## Recommended Fix
Do not create an 8 MB-eligible builder fit unless both kernel and rootfs usage measurements are present and within the layout limits. Preserve incomplete reports as unknown for the wizard's no-report safeguard, and test a report with `flash_mb=8` and omitted usage.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. FPV cards can offer firmware builds ✓ Resolved
Description
FPVMap classifies releases solely by edition name and never checks whether the selected asset
comes from builder. When firmware and builder publish the same FPV name, firmware wins that indexed
name, but the live low-latency card still presents it as an installable builder stack.
Code

service/internal/firmware/availability.go[R79-82]

+			for _, e := range idx.Releases(BoardFor(soc, idx, ft), ft) {
+				if slices.Contains(FPVEditions, e) && !slices.Contains(eds, e) {
+					eds = append(eds, e)
+				}
Evidence
The index explicitly retains firmware's asset on a name collision, while the new map includes every
release whose name occurs in FPVEditions. The low-latency script uses that map to generate
installation buttons.

service/internal/builds/source.go[55-64]
service/internal/firmware/availability.go[73-89]
frontend/apps/site/src/components/pages/LowLatency.astro[263-275]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The low-latency feed can advertise a firmware-owned release as a builder FPV stack when names collide.
## Fix Focus Areas
- service/internal/firmware/availability.go[73-89]
- service/internal/builds/source.go[55-64]
## Recommended Fix
Before adding an edition to the FPV map, resolve its board/storage asset and require `RepoBuilder`. Add a collision test in which firmware owns the indexed name.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Install buttons can open Lite for NAND-only FPV builds ✓ Resolved
Description
FPVMap adds a SoC's FPV editions from both the nor and nand releases into one list.
/low-latency, both the prerendered page and the live correction script, always links to
?rom=nor16m&ver=. If builder publishes an FPV edition for a SoC only as a NAND tarball
(BuilderEdition accepts openipc.-nand-.tgz), the card shows an install button anyway. The
installer's NOR 16M menu doesn't offer that edition, so it quietly falls back to Lite, which is the
behaviour the PR's own openOn test confirms.
Code

service/internal/firmware/availability.go[R75-82]

+		for _, ft := range []string{"nor", "nand"} {
+			if !BootloaderPublished(soc, idx, ft) {
+				continue
+			}
+			for _, e := range idx.Releases(BoardFor(soc, idx, ft), ft) {
+				if slices.Contains(FPVEditions, e) && !slices.Contains(eds, e) {
+					eds = append(eds, e)
+				}
Evidence
FPVMap loops over []string{"nor", "nand"} and merges the editions with no record of which flash
type each came from. The page script builds ?rom=nor16m&ver=${edition} for every slug in
live.fpv. The wizard test shows that asking for an edition the chosen chip doesn't offer opens
Lite instead.

service/internal/firmware/availability.go[68-93]
frontend/apps/site/src/components/pages/LowLatency.astro[267-275]
frontend/apps/site/src/lib/wizard-menu.test.ts[278-280]
service/internal/firmware/builder_test.go[21-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
FPVMap merges NOR and NAND FPV editions, but /low-latency always links into the installer with rom=nor16m. An edition published only for NAND therefore opens as Lite.
## Fix Focus Areas
- service/internal/firmware/availability.go[68-93]
- frontend/apps/site/src/components/pages/LowLatency.astro[267-275]
## Recommended Fix
Build FPVMap from the `nor` releases only, where the NOR bootloader is published, because that is the chip the links open. The alternative is to emit the editions per flash type and have the page choose `rom=nand` when an edition is NAND-only. Add a test with a NAND-only FPV asset.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

6. Builder note can show for firmware-built editions 🐞 Bug ≡ Correctness
Description
Experts in Result.tsx shows the builder and sysupgrade notice based on settings.firmwareVersion
matching a builder edition name, without checking the selected asset’s repository. When firmware and
builder publish the same name, LoadIndex selects the firmware asset and the wizard links to its
tarball, but still tells the installer that the bundle comes from and is updated through builder.
Code

frontend/apps/site/src/components/wizard/Result.tsx[R629-631]

+                    {fromBuilder(settings.firmwareVersion) && (
+                      <p class="mt-2 mb-0">{install('flashing_footfs2.builder')}</p>
+                    )}
Evidence
source.go adds builder assets only when firmware has not already taken their names, so a name such
as fpv can resolve to a firmware asset. export.go uses the indexed asset’s Repo to construct the
wizard URL but does not pass that repository to the wizard document; the frontend instead checks
whether the edition name appears in editions.ts.

service/internal/builds/source.go[55-64]
frontend/apps/site/src/lib/editions.ts[8-12]
service/internal/wizard/export.go[192-200]
service/internal/wizard/export.go[191-200]
frontend/apps/site/src/lib/editions.ts[8-11]
frontend/apps/site/src/components/wizard/Result.tsx[620-631]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The builder notice is chosen from the edition name rather than the selected asset’s repository. If firmware publishes the same name, the wizard serves firmware’s bundle while claiming it comes from and is updated through builder.
## Fix Focus Areas
- frontend/apps/site/src/components/wizard/Result.tsx[625-631]
- service/internal/wizard/export.go[191-210]
- service/internal/wizard/export.go[392-397]
- service/internal/builds/source.go[55-64]
## Recommended Fix
Expose the selected asset’s `Repo` in the wizard document, on each relevant combination or published entry, either as a repository value such as `firmware_repo` or as a `from_builder` boolean. Render the notice only when that value identifies the asset as builder-owned, and cover the case where firmware wins a name collision.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Pre-rendered wfb-ng links open Lite after the rename ✓ Resolved
Description
FPV_STACKS prerenders every wfb-ng install link as ver=fpv. Once builder publishes wfbng,
NewIndex drops fpv from Releases for that board. Until the page is rebuilt, any visitor whose
availability fetch fails or is served stale (the response is cacheable for 5 minutes, with up to an
hour of stale-while-revalidate) clicks a link that the installer silently turns into Lite.
Code

frontend/apps/site/src/data/fpv-stacks.ts[R26-27]

+    socs: Object.fromEntries(['ssc338q', 'ssc30kq', 'ssc378qe', 'gk7205v200', 'gk7205v210', 'gk7205v300',
+      'hi3516ev200', 'hi3516ev300'].map((s) => [s, 'fpv'])),
Evidence
The index removes fpv whenever wfbng is present. The wizard test shows that an edition the menu
doesn't offer becomes Lite. The live correction only runs when the fetch succeeds and contains an
fpv object.

service/internal/firmware/index.go[146-154]
frontend/apps/site/src/lib/wizard-menu.test.ts[278-280]
frontend/apps/site/src/components/pages/LowLatency.astro[252-261]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Prerendered /low-latency links use ver=fpv. After builder starts publishing wfbng, the wizard no longer offers fpv and those links open Lite.
## Fix Focus Areas
- frontend/apps/site/src/data/fpv-stacks.ts[26-27]
- service/internal/firmware/index.go[146-154]
## Recommended Fix
In the wizard's link handling (`openOn`), map a requested `fpv` to `wfbng` when only `wfbng` is offered, and the reverse. That way a stale link still opens the wfb-ng edition.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can route each severity your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread service/internal/wizard/export.go Outdated
Comment thread service/internal/builds/source.go
Comment thread service/internal/builds/source.go
Comment thread service/internal/firmware/availability.go Outdated
Comment thread service/internal/firmware/availability.go Outdated
Comment thread frontend/apps/site/src/components/wizard/Result.tsx
Comment thread frontend/apps/site/src/data/fpv-stacks.ts
…s, fpv links survive the rename

- fitsEight: a builder edition with no report is not 8 MB whether its
  tarball is NOR or NAND (a NAND-only edition reaches NOR combinations
  when NOR has nothing published).
- A builder size report missing either partition's usage is no report,
  not zeros that pass for an 8 MB fit.
- The availability feed's fpv map lists NOR builds from builder only:
  /low-latency links the 16 MB NOR installer, which would open a
  NAND-only edition as Lite, and a firmware-built name is not a builder
  stack.
- The installer reads ver=fpv as wfbng once only wfbng is published, so
  a page prerendered before builder's rename, or a kept permalink, does
  not quietly open on Lite.
@openipc-ai
openipc-ai merged commit be96059 into master Oct 7, 2026
4 checks passed
@openipc-ai
openipc-ai deleted the fpv-editions-390 branch October 7, 2026 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant