Koder Suite — `.deb` → Hub Apt Reconciliation Registry

Source of truth for the mapping between (a) the Debian .deb packages that the Koder Kodix ISO installs via hook 0060, (b) the Flow release tags that produce those .deb assets, (c) the Hub catalog slugs that store the published artifact metadata, and (d) the Debian Package: field emitted in the apt repo's Packages index.

Lives at meta/docs/stack/registries/ per policies/content-location.kmd (registries → tabular sources of truth). Authored by hub#139 (2026-05-20) to resolve the slug/package-name divergence surfaced when populating hub.koder.dev/apt with real .debs.

How the four names relate

Per specs/naming/forms.kmd R1-R6 + policies/naming-aliases.kmd + the RFC-007 Package: convention codified in depot/handlers/apt.go:

  • Canonical slug — kebab-case identifier registered in

    meta/docs/stack/registries/component-names.md. Used as the Hub URL segment (hub.koder.dev/apps/<slug>) and as the path prefix when publishing.

  • .deb Package name — the literal Package: field inside the

    .deb control file. Comes from koder.toml / kpkg.toml / fpm invocations at build time. Apt clients install by this name (apt install <pkg>).

  • Flow tag path<area>/<sector>/v<X.Y.Z> per

    policies/releases.kmd. The .deb is attached as a release asset.

  • Android applicationId — reverse-DNS, lives in AppRow.PackageName

    per specs/binaries-and-cli/naming.kmd §11. Not relevant to apt; listed here only to surface the conflict that depot/handlers/apt.go's debPackageName had to navigate (overriding it via PackageName would emit invalid Debian names like dev.koder.koder_store).

koder-suite mapping (all variants / base substrate)

Hub slug .deb Package Flow path Latest tag / version required? First Hub publish
koder-box koder-box infra/net/box 1.1.0 (manual publish; no Flow tag in this checkout) yes 2026-06-07 (BOX-160; amd64 apt-install e2e PASS)

koder-suite mapping (desktop variant)

Hub slug .deb Package Flow path Latest tag (2026-05-20) required? First Hub publish
kompose kompose infra/linux/x infra/linux/x/v0.4.0 yes 2026-06-06 (kompose rebrand)
kolide-shell kolide-shell infra/linux/kolide infra/linux/kolide/v0.3.4 yes 2026-05-20 (hub#139 bulk)
kolide-services kolide-services infra/linux/kolide infra/linux/kolide/v0.3.4 yes 2026-05-20 (hub#139 bulk)
koder-settings koder-settings core/settings core/settings/v1.0.0 yes 2026-05-20 (hub#139 bulk)
koder-term koder-term products/dev/kterm products/dev/kterm/v1.32.1-deb (published as 1.32.1) opt 2026-05-20 (hub#139 bulk)
koder-drive-desktop koder-drive-desktop products/horizontal/drive products/horizontal/drive/v1.4.1 yes 2026-05-20 (hub#139 bulk)
koder-grid koder-grid products/dev/grid products/dev/grid/v3.0.4 opt 2026-05-20 (hub#139 bulk)
koder-calc koder-calc products/horizontal/calc products/horizontal/calc/v1.0.0 opt 2026-05-20 (hub#139 bulk)
koder-snap koder-snap products/horizontal/snap products/horizontal/snap/v1.0.0 opt 2026-05-20 (hub#139 bulk)
koder-pixel koder-pixel products/horizontal/pixel products/horizontal/pixel/v1.7.0 opt 2026-05-20 (hub#139 bulk)
koder-kruze koder-kruze products/horizontal/kruze products/horizontal/kruze/v1.0.23-deb (published as 1.0.23) opt 2026-05-20 (hub#139 bulk)
koder-hub koder-hub products/dev/hub products/dev/hub/v2.31.2 opt 2026-05-20 (hub#139 bulk)
koder (no .deb yet) products/dev/koder-tools opt pending first koder-tools release
koder-device koder-device core/device core/device/v0.1.0 req 2026-06-02 (DEVICE-002 — CLI+service, headless)
koder-device-gui koder-device-gui core/device core/device/v0.1.0 opt 2026-06-02 (DEVICE-002 — Flutter GUI; Depends: koder-device)

Termux / TUR absorption (hub#162, 2026-05-24)

Until 2026-05-24, Koder maintained a second apt repo at tur.koder.dev (TUR-style) for Termux/Android packages. Per policies/reuse-first.kmd and policies/self-hosted-first.kmd's "single canonical apt source" principle, that repo's koder-* content was bulk-published into hub.koder.dev/apt under hub#162 Option A.

3 packages absorbed:

Hub slug .deb Package Version (latest) Arch First Hub publish
koder-act-runner koder-act-runner 1.0.2-koder2 aarch64 2026-05-24 (hub#162)
koder-archive-keyring koder-archive-keyring 0.1.0~rc.1 all 2026-05-24 (hub#162)
koder-creds-helper koder-creds-helper 0.3.0 all 2026-05-24 (hub#162)

Suite landing (per apt.go::versionFitsSuite):

  • 1.0.2-koder2 lands in pre + dev (hyphen tail = pre-release).
  • 0.1.0~rc.1 lands in dev only (~ tail doesn't match

    semver-pre).

  • 0.3.0 lands in stable + pre + dev (clean semver-core).

End-user Termux source lines to consume the absorbed packages:

deb [trusted=yes] https://hub.koder.dev/apt stable main
deb [trusted=yes] https://hub.koder.dev/apt pre main

Keeping Hub apt in sync with TUR (hub#163, 2026-05-24)

Per-version sync from tur.koder.dev into Hub apt is automated via Koder/termux-packages-koder repo at .github/workflows/koder-hub-mirror.yml + scripts/koder-hub-mirror.py. The mirror is idempotent (Hub returns replaced=true on re-publish) and pulls every koder-* tuple it finds across the (suite × arch) matrix.

Scheduled trigger: 03:17 + 15:17 UTC daily.

Manual trigger (operator runbook):

# From any laptop with Flow access:
git clone --depth 1 https://flow.koder.dev/Koder/termux-packages-koder.git
cd termux-packages-koder
KODER_HUB_PUBLISH_KEY=$(ssh s.khost1 'incus exec hub -- grep publish_key /etc/koder-hub/config.toml | cut -d\" -f2') \
  python3 scripts/koder-hub-mirror.py

Outputs one line per tuple: OK <slug> v=<ver> arch=<arch> replaced=<true|false>.

Status: workflow + script deployed 2026-05-24. Auto-trigger via Flow Actions blocked on Flow runner ecosystem (the registered laptop act_runner hasn't successfully executed any of the 79 historical runs in this repo — separate concern tracked as a flow follow-up). The script works standalone today; manual run covers the gap.

koder-suite mapping (server variant)

The all-variant base substrate above is required by the server image too. Server-only entries remain optional in the server koder-suite-packages.txt; they'll flip to required once each component's .deb release pipeline stabilises. None of the server-only entries are published to Hub apt yet — server bulk-import is the follow-up to hub#139.

Hub slug (planned) .deb Package Flow path Latest tag
koder-id-daemon koder-id-daemon services/foundation/id not yet released as .deb
koder-reporter koder-reporter services/foundation/reporter not yet released as .deb
koder-certs koder-certs services/foundation/certs not yet released as .deb
koder-billing koder-billing services/foundation/billing not yet released as .deb
koder-jet koder-jet infra/net/jet not yet released as .deb
koder-kdb-next koder-kdb-next infra/data/kdb not yet released as .deb

Drift notes

Two recurring drift sources to watch:

  1. -deb version-tag suffix. Several components (kterm, kruze) tag

    their .deb releases as vX.Y.Z-deb to distinguish from the parent Flutter build (which has no Debian-side artifact). Hub's versionFitsSuite classifies vX.Y.Z-deb as a semver pre-release (excluded from stable), so the bulk-publish script strips the -deb suffix before POSTing to /api/v1/publish/{slug}. Pre/dev suite consumers wanting the raw -deb version can read from dev or pre.

  2. Production-catalog slug drift. The Hub catalog DB drifted from

    the seed list at some point — kterm ended up as slug koder-term in prod, and the seed's slug-rename loop can't re-rename when the target kterm would collide with the seed-created entry. Reconcile manually if/when the canonical name matters; for apt purposes koder-term is a perfectly valid Debian Package name and installs the same .deb.

How to publish a new component's .deb to Hub

Until hub#103 wires a Gitea Action that runs on every release tag, the one-shot script lives in this ticket's closure notes. Pattern:

PUBLISH_KEY=$(ssh s.khost1 "incus exec hub -- bash -c \"grep publish_key /etc/koder-hub/config.toml | awk -F'\\\"' '{print \\\$2}'\"")
curl -sf -X POST "https://hub.koder.dev/api/v1/publish/<slug>" \
  -H "Authorization: Bearer $PUBLISH_KEY" \
  -F file=@<deb_path> \
  -F version=<semver-core>   \  # strip any `-deb` / `-prerelease` suffix
  -F format=deb \
  -F platform=linux \
  -F arch=x86_64           # or aarch64 / universal

Uploads > ~100 MiB are best sent via the internal endpoint (http://127.0.0.1:9420/api/v1/publish/<slug> from inside the hub container) to avoid edge timeouts on the public URL. See hub#139 closure for the kruze 442 MiB precedent.

Update cadence

Refreshed by hub#139 (2026-05-20) when first populating apt. Future updates: any new Koder-Kodix-installable component should add a row at publish-pipeline-wiring time; renames should add a "previous slug → new slug" entry under a ## Drift notes section above. CI ownership of this file lives with the hub team (depot/seed.go owners).