Element Call reaches production only as the embedded npm package, which webpack
copies into ThreadNet-Web under /widgets/element-call/. The embedded build sets
publicDir: false — upstream reasons that public/ holds nothing but the favicon,
which stopped being true when the model assets landed there.
Verified rather than assumed: with the upstream value everything builds, the
standalone bundle works, and the filter is dead only inside the widget, 404ing on
the model. That is the failure this would have shipped.
The package grows from about 41 to 66 MB, measured — most of what was already
there is source maps and the crypto and vision wasm.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The WebRTC noise suppression estimates a running noise profile, so it removes
stationary noise but not keystrokes, which are transient and never look like
noise to it. Chiclet keyboards are as affected as mechanical ones. DeepFilterNet3
runs client-side as a LiveKit track processor and removes them.
Off by default and the model is only fetched once a user switches it on, so
nobody pays the download who does not want the filter. Default strength is 35
percent rather than full: measured, that already gives keystrokes gone with the
voice still natural, and more attenuation only adds artefact risk.
Assets ship with us instead of the package's default CDN, which would report
every participant's IP to a third party at call start and tie call setup to
foreign infrastructure. The Dockerfile gzips the model wasm, which the existing
top-level glob missed — 4.1 MB instead of 15.7 MB per client.
Browser noise suppression is switched off while the filter runs so the two do not
work against each other. Regulation goes through the model's own attenuation
limit, so there is no dry/wet mixer and no delay compensation to get wrong.
Decision and measurements: management ADR-0018 and issue #0054.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Field test F-011 found four of five components carried no pointer file, so a
session landing here had no path to the group rules at all. CLAUDE.md is the
one-line pointer the check looks for; AGENTS.md links the canonical rules in the
management repo (with the Gitea mirror URL for readers outside the lab) and
otherwise carries only what is specific and easy to get wrong here.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Section 4 still described a manual/local npm publish with an untracked .npmrc - obsolete since publish_npm landed in .gitlab-ci.yml on 2026-08-06. Documents the actual job: manual trigger, GITEA_NPM_TOKEN, the empty-package guard, and the threadnet dist-tag.
Without VITE_APP_VERSION the bundle calls itself dev - in developer settings and in every error message. Someone reporting a call problem then cannot say which build they were on.
Set to the package version plus the short commit: the first says what was published, the second what was actually built. Between two publishes only the latter changes, and then it is the only thing that tells two builds apart.
Closesaxion1337.chat/threadnet-call#3
The anonymisation rewrite of 2026-08-07 gave every touched commit a new SHA, leaving the references in these documents pointing at objects that no longer exist. The mapping was reconstructed from the backup branches and each pair verified by tree and commit message before substituting.
Prefix lookups were built for lengths 7 to 12 and any ambiguous prefix would have been skipped; none were ambiguous across all 251 pairs.
Same trap as in ThreadNet-Web: a commit touching only docs/ produced a pipeline with zero jobs, which GitLab marks as failed - pipeline 187 on 2026-08-06. build_embedded is skipped by its changes rule and publish_npm depends on it, so nothing is left.
The path list is now a YAML anchor shared with build_embedded instead of a second copy. CI_PIPELINE_SOURCE == web stays allowed so publish_npm remains reachable after a docs-only commit.
Refs axion1337.chat/threadnet-call#1
0.19.2-threadnet.6 liegt mit 12,5 KB statt 12,8 MB in der Registry: package.json und Lizenzen, kein dist/. Woher der Upload kam, laesst sich nicht mehr klaeren - beide publish_npm-Laeufe von heute sind fehlgeschlagen, der eine vor dem Upload am fehlenden dist-tag, der andere danach mit 409. Die Nummer ist verbrannt, npm-Versionen sind nicht ueberschreibbar.
Der neue Check bricht ab, wenn embedded/web/dist weniger als 50 Dateien hat (erwartet ~150). Das kostet nichts und verhindert, dass diese Klasse Fehler noch einmal eine Versionsnummer verbrennt.
npm bricht ab, sobald eine Version wie 0.19.2-threadnet.6 ohne --tag veroeffentlicht werden soll - der Suffix macht sie zur Prerelease. "threadnet" statt "latest", denn latest soll nicht auf eine Vorabversion zeigen.
Refs axion1337.chat/threadnet-call#2
Meine erste Aussage "Logo.svg und LogoLarge.svg sind unreferenziert" war falsch - der Grep hatte icons/ herausgefiltert. Alle vier Logo-SVGs sind importiert und im Bundle; gerendert wird im Widget trotzdem keins, jeweils durch dieselbe HeaderStyle.Standard-Bedingung gesperrt. Das ist der belastbarere Befund, weil er an der Render-Bedingung haengt statt an einem Suchtreffer.
Refs axion1337.chat/threadnet-call#2
build_embedded sammelte embedded/web/dist, Vite schreibt aber nach dist/ - der Job lief seit jeher gruen und lud dabei NICHTS hoch ("WARNING: embedded/web/dist: no matching files"). publish_npm haengt per needs:artifacts daran und haette ein Paket ohne dist/ veroeffentlicht.
Upstream setzt den Pfad ueber das Download-Ziel des Artefakts; hier wird nach dem Build verschoben.
Refs axion1337.chat/threadnet-call#2
Die Datei setzt VITE_PRODUCT_NAME und landet damit im Bundle, stand aber nicht in der changes:-Liste von build_embedded - der vorige Commit haette also den Produktnamen geaendert, ohne dass die CI ueberhaupt baut.
Refs axion1337.chat/threadnet-call#2
VITE_PRODUCT_NAME ist upstream bereits an jeder Stelle vorgesehen (import.meta.env.VITE_PRODUCT_NAME || "Element Call"). Sie in .env.production zu setzen benennt das Widget vollstaendig um, ohne eine einzige Quelldatei anzufassen - also ohne Merge-Reibung beim naechsten Upstream-Update.
Die Inventur in docs/axion1337-fork.md haelt fest, was dadurch tatsaechlich umbenannt wird und was im Embedded-Build ohnehin nie erscheint: die Logo-SVGs rendern nur bei HeaderStyle.Standard, dem Nicht-Widget-Default; Startseite und Login gibt es nur standalone. Die deutschen matrixRTCMode-Beschreibungen bleiben bewusst stehen - sie reden ueber fremde Gegenstellen, nicht ueber uns.
Refs axion1337.chat/threadnet-call#2
Registry-Entscheidung evidenzbasiert: das Package ist pnpm-Dependency von
ThreadNet-Webs apps/web, der Lockfile pinnt die Tarball-URL auf rohana -
Registry bleibt dort. Publish-Auth ueber CI-Variable GITEA_NPM_TOKEN statt
lokaler Klartext-.npmrc.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>