#0055 is done: ThreadNet-Web be323ed checks in an .npmrc binding @sorb to rohana. The bump that mattered was not the file but what upstream's .gitignore does with it - it ignores /.npmrc, so the naive fix would have stayed local while CI kept resolving against npmjs. Measured in an isolated tree: without the file pnpm goes to npmjs and fails, with it the scope resolves to rohana at the integrity hash the lockfile already carries, and with rohana unreachable the install fails instead of falling back. threadnet-call only publishes and already sets the scope in its own CI; gitops never touches it. ThreadNet-Web was the only consumer. Four issues no longer describe reality, each verified rather than assumed: - #0091 (gitops#61) was fixed when it was written - on_conflict: fail shipped in ef04d86 and the MAS pod has run that config since 2026-08-11T14:08:41Z. Its one deliberate remainder became #0043, which is closed and verified live. - #0079 (gitops#46) asked for the Gitea migration and a central view. The migration ran; the central view was decided the other way round - repo canonical, GitLab mirrored (ADR-0012/0019) - which also answers the reachability trade-off it left open, and better than its three options did. - #0075 (gitops#40) is rejected, not done: it wanted new issues to appear in the Gitea kanban automatically. Issues no longer live in Gitea and the board is script-written. Nothing was accomplished; the question dissolved. - #0098 is a rollout record whose only remainder, the macOS build, is #0022. Three AARs move to harvested - every open item in them is tracked as an issue. Checked and still accurate, so left alone: the wiki branch still exists on both remotes (#0019), docs/TASKS.md and oldwiki/ are still there (#0085), element-web-docs still names live resources (#0086), res/themes/element persists (#0100), only WIKI_CANONIZE_TOKEN is set so TURN rotation still lacks its token (#0084), gameserver still has zero push mirrors (#0032), the broken .6 package is still published (#0101), and options.ts still builds simulcast layers regardless of codec, which is what blocks VP9 (#0057). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
130 lines
6.4 KiB
Markdown
130 lines
6.4 KiB
Markdown
---
|
|
type: issue
|
|
id: "0055"
|
|
status: done
|
|
created: 2026-08-16
|
|
milestone: M2
|
|
priority: medium
|
|
area: security
|
|
related:
|
|
- "docs/issues/0054-ki-geraeuschunterdrueckung-element-call.md"
|
|
- "docs/adr/0018-ki-geraeuschunterdrueckung-clientseitig-opt-in.md"
|
|
- "docs/adr/0001-gitlab-kanonisch-push-mirror.md"
|
|
gitlab_iid: "39"
|
|
---
|
|
|
|
# Issue-0055: `@sorb`-Scope in ThreadNet-Web ist nirgends auf rohana festgelegt
|
|
|
|
## Problem / Motivation
|
|
|
|
`ThreadNet-Web` bezieht `@sorb/threadnet-call-embedded` aus der Gitea-npm-Registry auf rohana,
|
|
aber **im Repo steht nirgends, dass der Scope `@sorb` dorthin zeigt**. Es gibt weder eine
|
|
`.npmrc` im Wurzelverzeichnis noch in `apps/web`, und die CI setzt auch keine.
|
|
|
|
Dass es trotzdem funktioniert, liegt allein am Lockfile: `pnpm-lock.yaml` pinnt die vollständige
|
|
Tarball-URL
|
|
|
|
```
|
|
tarball: https://rohana.axion1337.de/api/packages/sorb/npm/%40sorb%2F…tgz
|
|
```
|
|
|
|
und die CI installiert mit `--frozen-lockfile`. Solange niemand die Version anhebt, wird der
|
|
Scope nie aufgelöst — und der fehlende Eintrag fällt nicht auf.
|
|
|
|
Aufgefallen beim Anheben auf `0.19.2-threadnet.8` (#0054): `pnpm install` griff nach
|
|
`registry.npmjs.org` und brach ab.
|
|
|
|
```
|
|
ERR_PNPM_FETCH_404 GET https://registry.npmjs.org/@sorb%2Fthreadnet-call-embedded: Not Found
|
|
```
|
|
|
|
Die Anhebung ging nur durch, weil der Scope für diesen einen Aufruf von Hand gesetzt wurde:
|
|
|
|
```sh
|
|
env 'npm_config_@sorb:registry=https://rohana.axion1337.de/api/packages/sorb/npm/' pnpm install
|
|
```
|
|
|
|
Das steht in keiner Doku. Der nächste, der die Abhängigkeit anhebt, läuft in dieselbe Wand.
|
|
|
|
## Warum das mehr ist als eine Unbequemlichkeit
|
|
|
|
Der heutige Fehlschlag ist **laut** — 404, Abbruch, niemand baut versehentlich etwas Falsches.
|
|
Laut ist gut. Der Punkt ist, dass die Lautstärke von einer Bedingung abhängt, die uns nicht
|
|
gehört: `@sorb/threadnet-call-embedded` existiert auf `registry.npmjs.org` **derzeit nicht**.
|
|
|
|
Registriert dort jemand diesen Namen, löst genau derselbe Befehl nicht mehr mit 404 auf, sondern
|
|
**erfolgreich — gegen ein fremdes Paket**. Das ist das Muster, das als *dependency confusion*
|
|
bekannt ist, und die Bedingung dafür ist nicht „ein Angriff auf uns", sondern „jemand legt einen
|
|
Scope-Namen an". Der Schutz besteht heute ausschließlich darin, dass ein Name auf einer fremden
|
|
Registry noch frei ist.
|
|
|
|
Verschärfend: Der Fehler träfe genau den Moment, in dem jemand eine Version anhebt — also den
|
|
Moment, in dem eine neue Abhängigkeit ohnehin erwartet wird und ein Download nicht auffällt.
|
|
|
|
Das ist dieselbe Klasse wie die Befunde aus #0054 und der Backup-Reihe: **die Absicherung besteht
|
|
nicht, sie ergibt sich nur zufällig aus dem aktuellen Zustand.** Sie „meldet" auch nichts — sie
|
|
funktioniert stillschweigend, bis sie es nicht mehr tut.
|
|
|
|
## Acceptance
|
|
|
|
- Eine **eingecheckte** `.npmrc` in `ThreadNet-Web` bindet den Scope fest:
|
|
`@sorb:registry=https://rohana.axion1337.de/api/packages/sorb/npm/`
|
|
- Ein Anheben der Version funktioniert im **frischen Klon ohne Zusatzschritte** — das ist der
|
|
eigentliche Nachweis, nicht das Vorhandensein der Datei.
|
|
- Gegenprobe: Ein Lauf mit absichtlich unerreichbarer rohana **scheitert**, statt auf
|
|
`registry.npmjs.org` auszuweichen.
|
|
- Die anderen Repos der Gruppe sind auf denselben Befund geprüft: Wer sonst noch `@sorb`-Pakete
|
|
zieht, hat dieselbe Lücke (`threadnet-call` selbst publisht nur, konsumiert aber ggf. auch).
|
|
- Der Auslieferungsweg in `ThreadNet-Web:docs/axion1337-fork.md` nennt den Befehl zum Anheben.
|
|
|
|
## Notes
|
|
|
|
**Kein Token nötig.** Der Lesezugriff auf die Registry ist anonym möglich (nachgeprüft: der
|
|
Paket-Index antwortet ohne Authentifizierung). Die `.npmrc` enthält damit **nur eine URL und kein
|
|
Geheimnis** und kann bedenkenlos eingecheckt werden — das ist der Grund, warum hier kein
|
|
Secrets-Handling dranhängt.
|
|
|
|
**Warum nicht einfach dokumentieren:** Ein Satz in der Fork-Doku würde den 404 erklären, aber die
|
|
`registry.npmjs.org`-Auflösung nicht verhindern. Nach der Lehre aus #0053 und dem Bindmount-Fall
|
|
ist Aufschreiben hier ausdrücklich **nicht** die Maßnahme: die Regel war beide Male vorhanden und
|
|
hat den Fehler nicht verhindert. Wirksam ist die eingecheckte Datei, weil sie den falschen Weg
|
|
gar nicht erst offen lässt.
|
|
|
|
**Verwandt, aber getrennt:** Bei der Gelegenheit ist aufgefallen, dass der Job `publish_npm` in
|
|
`threadnet-call` `allow_failure: true` trägt — ein *scheiternder* Publish färbt die Pipeline
|
|
nicht rot. Das ist ein eigener Befund und gehört nicht in dieses Issue; hier nur notiert, damit
|
|
er nicht verloren geht.
|
|
|
|
## Erledigt 2026-08-18 — `.npmrc` eingecheckt, Auflösung nachgewiesen
|
|
|
|
Umgesetzt in `ThreadNet-Web` (`be323ed`): `.npmrc` im Wurzelverzeichnis bindet
|
|
`@sorb` an die Registry auf rohana.
|
|
|
|
**Ein Fund beim Umsetzen, der den naiven Fix stillschweigend zunichtegemacht hätte:**
|
|
Upstreams `.gitignore` enthält `/.npmrc` (Zeile 7) — sinnvoll, wo die Datei Tokens trägt.
|
|
Die Datei wäre also lokal geblieben, ohne dass irgendetwas gemeldet hätte; CI und frischer
|
|
Klon hätten weiter gegen npmjs aufgelöst. Die Ausnahme steht jetzt ausdrücklich mit
|
|
Begründung im `.gitignore` (`!/.npmrc`), damit der nächste Upstream-Merge die Lücke nicht
|
|
wieder aufmacht. Dieselbe Klasse wie die Befunde aus #0054: gemeldeter Erfolg ohne Wirkung.
|
|
|
|
**Abnahme — in einem isolierten Baum gemessen, nicht angenommen:**
|
|
|
|
| Prüfung | Ergebnis |
|
|
|---|---|
|
|
| ohne `.npmrc` (heutiger Zustand) | löst gegen `registry.npmjs.org` auf, bricht ab |
|
|
| mit `.npmrc`, frische Auflösung ohne Zusatzschritt | Tarball von `rohana.axion1337.de`, Integrity identisch mit dem Repo-Lockfile |
|
|
| Gegenprobe rohana unerreichbar | `ERR_PNPM_META_FETCH_FAIL`, **kein** Ausweichen auf npmjs, kein Lockfile |
|
|
| `pnpm install --frozen-lockfile` (CI-Weg) | grün, Lockfile unverändert |
|
|
|
|
**Andere Repos geprüft:** `threadnet-call` *publisht* das Paket nur und schreibt die
|
|
Scope-Zeile in seiner CI bereits selbst (`.gitlab-ci.yml`); es konsumiert keine
|
|
`@sorb`-Pakete. In `gitops` kommt der Scope nicht vor. `ThreadNet-Web` war der einzige
|
|
Konsument — die Lücke ist damit vollständig geschlossen, nicht nur an einer Stelle.
|
|
|
|
**Dokumentiert:** `ThreadNet-Web:docs/axion1337-fork.md` hat jetzt einen Abschnitt
|
|
„Element Call anheben" mit dem Weg ohne Umgebungsvariable, dem `--dir`-statt-`--filter`
|
|
Fallstrick und der Prüfung, dass die Tarball-URL auf rohana zeigt.
|
|
|
|
**Nicht angefasst:** `allow_failure: true` auf `publish_npm` — eigener Befund, liegt
|
|
weiterhin bei sorb.
|