The goal was to extract all issues from a Redmine instance, anonymize the data, and build a local RAG system for semantic search and Q&A.
Just like with the previous experiment with Bugzilla it started with data extraction. I planned to make a simple bulk download via Redmine API. Then came the first problem. Redmine’s API doesn’t return journal entries (comments) when using the project-level endpoint, even with the include=journals parameter. I tried out different ways but nothing worked. The solution was, after all, to change the strategy and fetch each issue individually via /issues/{id}.json. This was much slower but guaranteed complete data including all comments.
Esta vez voy justo, y me sabe mal porque el ponente de la charla «Fediverso y redes sociales no propietarias #Vamonosjuntas» es David Marzal, uno de los miembros más activos de la podcasfera linuxera que con su KDE Express nos informa con una periodicidad envidiable de las últimas novedades del mundos del Software Libre. Así que voy al grano: mañana viernes de 11 a 13 estáis invitados a asistir a su charla que realizará en el Campus dels Tarongers, Biblioteca de Ciencias Sociales. Sigue leyendo para tener más informacion.
Fediverso y redes sociales no propietarias #Vamonosjuntas
Ya comento que no podré asistir pero que si estuviera por València ni me lo pensaría. David Marzal es buen comunicador y asistir a sus charlas siempre es un lujo.
Es por ello que este viernes 5 de diciembre, a las 11 horas tenéis una cita en el Aula de Formación de la Biblioteca de Ciencias Sociales del Campus de Tarongers, Universidad de Valencia si queréis saber la importancia de tener redes libres y descentralizadas, cuyo propósito sea facilitar la comunicación y no intoxicar la opinión pública y ganar dinero con vuestros datos,
Pero mejor que os lo expliquen los organizadores:
Nosotras también estamos hartas de las redes sociales tóxicas, así que nos hemos mudado a un nuevo barrio: el fediverso. Te invitamos a formar parte de esta comunidad, donde apostamos por un internet más humano, libre y colaborativo. Además, asumimos el compromiso de enfrentar los retos que supone nutrir una herramienta colectiva y descentralizada como ésta, prescribiendo su utilización así como sosteniéndola mediante la movilización de recursos desde la corresponsabilidad que iniciativas como ésta requieren. David Marzal es administrador de sistemas GNU/Linux de profesión, apasionado por el software libre y la sostenibilidad de vocación. Activista en asociaciones como GNU/Linux Valencia, KDE España o Residuo Cero de la Región de Murcia. Actividad gratuita con aforo limitado a 20 personas, por riguroso orden de inscripción. La inscripción se realiza vía correo-e: cde@uv.es Con la colaboración del Servei de Biblioteques i Documentació de la Universitat de València.
Información básica:
Fediverso y redes sociales no propietarias #Vamonosjuntas Profesor: David Marzal Viernes, 5 de diciembre de 2025 11-13 h. Campus dels Tarongers. Biblioteca de Ciencias Sociales. Aula de formación.
Hoy me complace compartir con vosotros un nuevo episodio de Compilando Podcast, que ha vuelto con fuerza en forma de episodios tipo píldora muy instructivos. En esta ocasión se trata del episodio 64 que lleva por título «LOUVRE el arte de la ciberseguridad» donde Paco nos hace reflexionar sobre uno de las aspectos que día a día se hace más importante, la ciberseguridad, y su relación con el arte.
LOUVRE el arte de la ciberseguridad en Compilando Podcast
En palabras del gran Paco Estrada, extraídas de la nueva web de Compilando Podcast y que sirven de introducción del episodio 63:
Una de las mayores instituciones culturales del mundo, el Museo del Louvre, fue protagonista de un suceso que ha dado la vuelta al planeta. Pero más allá del titular y de la famosa contraseña, este episodio no busca hablar del robo, sino de lo que nos revela sobre la naturaleza humana, la tecnología y… el arte.
EnCompilando Podcast reflexionamos sobre cómo la ciberseguridad, más que una ciencia exacta, es también una forma de arte: una combinación de técnica, sensibilidad y cultura digital. Porque proteger sistemas no es solo cuestión de software o hardware, sino de conciencia, de educación y de esa mirada que sabe cuidar los detalles invisibles.
Un episodio para pensar en cómo la destreza, la atención y la responsabilidad se entrelazan también en el mundo digital.
Escúchalo y descubre por qué, incluso en la era de la Inteligencia Artificial, pensamos que la ciberseguridad sigue siendo, ante todo, un arte.
Dentro del mundo de los audios de Software Libre, que los hay muchos y de calidad, destaca uno por la profesionalidad de la voz que lo lleva, el gran Paco Estrada, y por el mimo con el que está hecho. No es por nada que ganó el Open Awards’18 al mejor medio, un reconocimiento al trabajo realizado por la promoción .
A modo de resumen, Compilando Podcast es un proyecto personal de su locutor Paco Estrada que aúna sus pasiones y que además, nos ofrece una voz prodigiosa y una dicción perfecta.
When my family moved to a new place. In our previous home we had a district heating service that included unlimited hot water for a fixed price. That was awesome - not very environmentally friendly and actually not very cheap, but we never ran out of hot water.
In our new home we are independent from the city’s hot water services. This is good because we pay exactly for the energy we use. It means that we have a 300-liter hot water heater that we turn on when we want to make as much hot water as we need. In most households such a hot water boiler has a thermostat set to a specific temperature and the heater keeps all 300 liters of water as hot as it is set. I do not like this, because regardless of how great the insulation on the water tank is, it loses temperature over time. I needed a smarter system.
Es increíble el trabajo de promoción que está realizando Nate en su blog, desde hace más del tiempo que puedo recordar, ha sido replicado en ocasiones por Carl Schwan hablando de aplicaciones. Igual que Nate, se trata de un resumen de las novedades más destacadas, pero no en forma de telegrama, sino de artículo completo. Dado que en la actualidad tenemos herramientas que nos facilitan la traducción y la edición voy a intentar hacer algo que es simple pero requiere constancia: promocionar dichos artículos facilitando la información a la comunidad hispana que no domina el inglés. Al mismo tiempo hará que yo esté al día y que me entere bien de todo. Bienvenidos pues al artículo de la serie de aplicaciones «Últimas dos semanas en las aplicaciones de KDE«. Espero que os gustey que os ponga los dientes largos viendo lo que nos espera.
Últimas dos semanas en las aplicaciones de KDE
Nota: artículo original en Blogs KDE. Traducción realizada utilizando Perplexity. Esta entrada está llena de novedades en las aplicaciones de la Comunidad KDE.
¡Bienvenido a una nueva edición de «This Week in KDE Apps»! Cada semana (o casi) cubrimos todo lo posible de lo que está sucediendo en el mundo de las aplicaciones de KDE. Todavía estamos realizando nuestras campañas de recaudación de fondos y en las últimas 48 horas, gracias al increíble apoyo de nuestros usuarios, hemos recaudado más de €90.000. ¡Sigue así y si puedes permitírtelo, dona en kde.org/donate! Cualquier cantidad ayuda. Volviendo a todo lo nuevo en el panorama de las aplicaciones de KDE, ¡vamos a ello!
Aplicaciones de viajes
Volker Krause publicó una entrada en su blog sobre el progreso actual de KDE Itinerary en octubre y noviembre. Esto incluye una página de búsqueda de viajes mejorada, control detallado para eliminar billetes, información de altitud en la vista de estado en vivo, ¡y más! Puedes leer todo eso en su blog.
Matan Ziv-Av añadió dos acciones de teclado en Konsole para enfocar la siguiente o anterior vista en modo de vista dividida (26.04.0 – enlace).
Sune Vuorela añadió una opción para activar o desactivar si Konsole escucha códigos terminales zmodem, que podría ocurrir accidentalmente al enviar un archivo binario (26.04.0 – enlace).
Oula V mejoró la función de grupos de feeds de Alligator. Ahora, al crear un grupo, se muestra un error si ya existe otro con el mismo nombre. También limpiaron la lista de grupos (26.04.0 – enlace).
Oula también corrigió algunos cierres inesperados tras editar un feed (25.12.0 – enlace) y Stephan Seitz corrigió problemas con la exportación OPML (25.12.0 – enlace).
Salvo Tomaselli reordenó los botones del menú, ahora abrir el artículo actual en un navegador externo es el primer botón (25.12.0 – enlace).
Alex Hermann hizo que las aplicaciones basadas en KIO como Dolphin mantengan los permisos de archivos copiados desde un servidor SFTP (enlace 1, enlace 2, enlace 3).
Joshua Goins continuó los esfuerzos para mejorar la Confianza y Seguridad en NeoChat y añadió soporte para reportar salas y usuarios (26.04.0 – enlace).
«renner 03» corrigió la integración de KRunner en NeoChat al ejecutar la aplicación en Flatpak (25.12.0 – enlace).
Navegadores
Konqueror Administrador de archivos KDE y navegador web
Stefano Crocco añadió una página de configuración para configurar marcadores rápidos en Konqueror. Estos marcadores rápidos son botones que permiten abrir rápidamente enlaces preconfigurados (26.04.0 – enlace).
Sandøy Hustad comenzó a implementar trabajo para que Trojita soporte Qt 6 (enlace).
Aplicaciones de terceros
Deskflow – Aplicación para compartir teclado y ratón
Chris Rizzitello lanzó Deskflow 1.25.0. Los principales cambios son soporte para un icono simbólico en la bandeja que se recolorea correctamente incluso usando el tema Twilight de Plasma; soporte para cambiar el idioma de la aplicación sin reiniciarla; y soporte inicial para el protocolo wl-clipboard de Wayland.
Giusy Digital continuó trabajando en unificar la nomenclatura de las diversas unidades físicas (por ejemplo, dB, Hz, …) en toda la aplicación (enlace).
Wellington Wallace portó algunas hojas de superposición a los diálogos Kirigami (enlace).
La organización KDE se ha vuelto importante a nivel mundial, y tu tiempo y contribuciones nos han ayudado a llegar hasta aquí. A medida que crecemos, necesitaremos tu apoyo para que KDE sea sostenible.
Puedes ayudar a KDE siendo un miembro activo de la comunidad y participando. Cada colaborador hace una gran diferencia en KDE: no eres un número ni una pieza más en una máquina. ¡Ni siquiera tienes que ser programador! Hay muchas cosas que puedes hacer: ayudar a encontrar y confirmar errores, e incluso quizás solucionarlos; contribuir con diseños para fondos de pantalla, páginas web, iconos e interfaces de aplicaciones; traducir mensajes y elementos de menús a tu idioma; promover KDE en tu comunidad local; y muchas más cosas.
También puedes ayudarnos donando. Cualquier contribución monetaria, por pequeña que sea, nos ayudará a cubrir los costos operativos, salarios, gastos de viaje para los colaboradores y, en general, a que KDE pueda seguir llevando Software Libre al mundo.
Para que tu aplicación sea mencionada aquí, por favor contáctanos en invent o en Matrix.
Recopilación y traducción del boletín mensual de noticias relacionadas con el software libre publicado por la Free Software Foundation.
¡El boletín de noticias de la FSF está aquí!
La Free Software Foundation (FSF) es una organización creada en Octubre de 1985 por Richard Stallman y otros entusiastas del software libre con el propósito de difundir esta filosofía, frente a las restricciones y abusos a los usuarios por parte del software privativo.
Por cierto este mes se cumplen 40 años de la creación de la FSF.
La Fundación para el software libre (FSF) se dedica a eliminar las restricciones sobre la copia, redistribución, entendimiento, y modificación de programas de computadoras. Con este objeto, promociona el desarrollo y uso del software libre en todas las áreas de la computación, pero muy particularmente, ayudando a desarrollar el sistema operativo GNU.
Mensualmente publican un boletín (supporter) con noticias relacionadas con el software libre, sus campañas, o eventos. Una forma de difundir los proyectos, para que la gente conozca los hechos, se haga su propia opinión, y tomen partido si creen que la reivindicación es justa!!
Por aquí te traigo un extracto de algunas de las noticias que ha destacado la FSF este mes de diciembre de 2025.
Sólo el software libre permite la soberanía digital
Del 24 de noviembre por la FSFE
El “Germany Stack” es un proyecto central de política digital del gobierno federal alemán. La FSFE pide que Stack se planifique en estrecha coordinación con los socios europeos y se implemente íntegramente como software libre, ya que sólo las cuatro libertades permiten la soberanía digital. Continúe leyendo para obtener más información sobre los detalles de esta solicitud del gobierno federal alemán, incluidos los principios en los que debería basarse el Stack.
El ejército estadounidense quiere arreglar su propio equipo. Los contratistas de defensa están intentando derribarlo.
Del 26 de noviembre por Boone Ashworth
Es probable que las disposiciones sobre el derecho a reparar en la Ley de Autorización de Defensa Nacional, que asegurarían la financiación para el ejército estadounidense en 2026, sean eliminadas del texto final del proyecto de ley a pesar de disfrutar de un amplio apoyo bipartidista, dijeron a WIRED fuentes familiarizadas con las negociaciones en curso.
Dicen que es probable que las disposiciones de la ley que permiten a los militares reparar sus propios equipos se eliminen por completo y se reemplacen con un plan de suscripción de datos como servicio que beneficie a los contratistas de defensa.
Cloudflare caído: la interrupción global afectó a gran parte de Internet
Del 18 de noviembre por Kate O’Flaherty
Aparentemente, la mitad de la red mundial estuvo caída a mediados de noviembre debido a una interrupción de Cloudflare, lo que demuestra que el software privativo no es tan estable y seguro como les gusta afirmar a sus proveedores.
Tantos sitios web que dependen de un único proveedor para servicios de red y seguridad conllevan grandes peligros, tanto para su libertad como para su capacidad de utilizar un programa en el que puede confiar para trabajar. El software libre ciertamente también puede sufrir interrupciones, pero hay muchas más soluciones cuando se utiliza software libre que con software privativo.
Si actualmente utiliza un programa que se vio afectado por la interrupción de Cloudflare (o su lugar de trabajo lo hace), ahora podría ser un buen momento para hablar sobre cambiar a un programa comparable que respete la libertad.
Estas son solo algunas de las noticias recogidas este mes, ¡¡pero hay muchas más muy interesantes!! si quieres leerlas todas (cuando estén traducidas) visita este enlace:
Existen decenas de eventos del Software Libre: Akademy, Gaudec, Akademy-es, talleres de Linux Center, LAS, Flisol, etc. A casi todos les doy promoción en el blog y el de hoy no puede ser una excepción. Os invito a asistir al Congreso esLibre 2026 en Melide, Galicia, un evento que destaca por su apuesta por la Comunidad. Si podéis no os lo perdáis.
Congreso esLibre 2026 en Melide
Los encuentros de desarrolladores y simpatizantes del Software Libre son una de las mejores cosas que suele ofrecer este mundo del conocimiento compartido, y el caso del congreso que promociono por primera vez en el blog no es una excepción.
Se trata de esLibre cuya edición de 2026 se celebrará en Melida (Galicia) el 17 y 18 de abril y que todavía está en la fase de recibir propuestas para charlas… pero date prisa que el plazo finalizará pronto.
En palabras de sus organizadores:
Después de un necesario año sabático por parte de las personas que desarrollan a lo largo del año todas las actividades necesarias, retomamos la edición correspondiente al año 2026 de la mano de la Asociación de usuarios de software libre da Terra de Melide MELISA y del Grupo de Amigos de GNU/Linux de Pontevedra GALPon.
Esta vez tendremos que desplazarnos a Melide una villa de algo más de 8.000 habitantes donde se unen el camino primitivo y el camino francés hacia Santiago, en la provincia de A Coruña y a 53km de Santiago.
Los distintos eventos se realizarán en los espacios socio culturales cedidos por el Concello de Melide concretamente en el Centro Sociocultural Mingos de Pita y en el Edificio Multiusos situados justo al lado uno del otro en la misma Praza das Universidades.
A long-waited feature for syslog-ng, the Kafka source, is getting ready soon. The development is still in progress, but you can already try it, and it is worth the effort. How? Using the very same tool the syslog-ng testing and release process relies on.
From this blog you can learn how to download and patch syslog-ng git sources and build packages for popular RPM and DEB Linux distributions. Once you have installable packages, comes the fun part: getting the Kafka source working.
As the founder of the openSUSE Innovator initiative, and a member of the openSUSE and Intel Innovator communities, I maintain my ongoing commitment to bringing cutting-edge technologies to the different flavors of the openSUSE Linux distribution.
With the arrival of NPU (Neural Processing Unit) devices, it has become possible to run LLMs and generative AI applications without relying on a dedicated GPU. In light of this advancement, we began the work of packaging the Intel NPU Driver into RPM for the openSUSE ecosystem. As a result of this collective effort, the openSUSE for Innovators initiative is proud to announce the official availability of this package to the community.
The Intel NPU is an inference accelerator integrated into Intel CPUs starting with the Intel® Core™ Ultra family (formerly known as Meteor Lake). It enables efficient and low-power execution of artificial neural network workloads directly on the processor.
The NPU is integrated into the processor die, designed to perform matrix operations of neural networks with high energy efficiency. Its architecture complements CPU and GPU, enabling intelligent offloading for ONNX models, computer vision pipelines, quantized models, and hybrid model operations with simultaneous use of CPU+GPU+NPU.
Participating in this project is a source of great satisfaction, as we know it will have a significant impact on future applications. As members of an open-source community, we have a responsibility to democratize emerging technologies and help reduce the digital divide, and this delivery is another important step in that direction.
I was reading a blog post about the testing strategy for the Wild
linker, when I came upon a link to cargo-mutants, a
mutation testing tool for Rust. The tool promised to be easy to set
up, so I gave it a try. I'm happy to find that it totally delivers!
Briefly: mutation testing catches cases where bugs are
deliberately inserted in the source code, but the test suite fails to
catch them: after making the incorrect changes, all the tests still
pass. This indicates a gap in the test suite.
Previously I had only seen mentions of "mutation testing" in passing,
as something exotic to be done when testing compilers. I don't recall
seeing it as a general tool; maybe I have not been looking closely
enough.
Setup and running
Setting up cargo-mutants is easy enough: you can cargo install
cargo-mutants and run it with cargo mutants.
For librsvg this ran for a few hours, but I discovered a couple of
things related to the way the librsvg repository is structured. The
repo is a cargo workspace with multiple crates: the librsvg
implementation and public Rust API, the rsvg-convert binary, and
some utilities like rsvg-bench.
By default cargo-mutants only seemed to pick up the tests for
rsvg-convert. I think it may have done this because it is the
only binary in the workspace that has a test suite
(e.g. rsvg-bench does not have a test suite).
I had to run cargo mutants --package librsvg to tell it to
consider the test suite for the librsvg crate, which is the main
library. I think I could have used cargo mutants --workspace to
make it run all the things; maybe I'll try that next time.
Initial results
My initial run on rsvg-covert produced useful results; cargo-mutants
found 32 mutations in the rsvg-convert source code that ought to
have caused failures, but the test suite didn't catch them.
The second run, on the librsvg crate, took about 10 hours. It is
fascinating to watch it run. In the end it found 889 mutations with
bugs that the test suite couldn't catch:
With the sorted results, I can clearly see how cargo-mutants gradually
does its modifications on (say) all the arithmetic and logic operators
to try to find changes that would not be caught by the test suite.
Look at the first two lines from above, the ones that refer to AcceptLanguage::any_matches:
The two lines from missed.txt mean that if the body of this
any_matches() function were replaced with just true or false,
instead of its actual work, there would be no failed tests:
135fnany_matches(&self,tag:&LanguageTag)->bool{136false// or true, either version wouldn't affect the tests137}}
This is bad! It indicates that the test suite does not check that
this function, or the surrounding code, is working correctly. And
yet, the test coverage report for those
lines shows that they are indeed getting executed by the test suite.
What is going on?
I think this is what is happening:
The librsvg crate's tests do not have tests for AcceptLanguage::any_matches.
The rsvg_convert crate's integration tests do have a test for
its --accept-language option, and that is what causes this code to
get executed and shown as covered in the coverage report.
This run of cargo-mutants was just for the librsvg crate, not for
the integrated librsvg plus rsvg_convert.
Getting a bit pedantic with the purpose of tests, rsvg-convert assumes
that the underlying librsvg library works correctly. The library
advertises support in its API for matching based on AcceptLanguage,
even though it doesn't test it internally.
On the other hand, rsvg-convert has a test for its own
--accept-language option, in the sense of "did we implement this
command-line option correctly", not in the sense of "does librsvg
implement the AcceptLanguage functionality correctly".
After adding a little unit test for AcceptLanguage::any_matches in
the librsvg crate, we can run cargo-mutants just for that the
accept_language.rs file again:
Great! As expected, we just have 1 missed mutant on that file now.
Let's look into it.
The function in question is now <impl fmt::Display for
AcceptLanguageError>::fmt, an error formatter for the
AcceptLanguageError type:
implfmt::DisplayforAcceptLanguageError{fnfmt(&self,f:&mutfmt::Formatter<'_>)->fmt::Result{matchself{Self::NoElements=>write!(f,"no language tags in list"),Self::InvalidCharacters=>write!(f,"invalid characters in language list"),Self::InvalidLanguageTag(e)=>write!(f,"invalid language tag: {e}"),Self::InvalidWeight=>write!(f,"invalid q= weight"),}}}
What cargo-mutants means by "replace ... -> fmt::Result with
Ok(Default::default()) is that if this function were modified to
just be like this:
then no tests would catch that. Now, this is just a formatter function;
the fmt::Result it returns is just whether the underlying call to
write!() succeeded. When cargo-mutants discovers that it can change this function to return
Ok(Default::default()) it is because fmt::Result is defined as
Result<(), fmt::Error>, which implements Default because the unit
type () implements Default.
In librsvg, those AcceptLanguageError errors are just surfaced as
strings for rsvg-convert, so that if you give it a command-line
argument with an invalid value like --accept-language=foo, it will
print the appropriate error. However, rsvg-convert does not make any
promises as to the content of error messages, so I think it is
acceptable to not test this error formatter — just to make sure it
handles all the cases, which is already guaranteed by its match
statement. Rationale:
There already are tests to ensure that the error codes are computed
correctly in the parser for AcceptLanguage; those are the
AcceptLanguageError's enumeration variants.
There is a test in rsvg-convert's test suite to ensure that it
detects invalid language tags and reports them.
For cases like this, cargo-mutants allows marking code to be
skipped. After marking this fmt implementation with
#[mutants::skip], there are no more missed mutants in
accept_language.rs.
Yay!
Understanding the tool
You should absolutely read "using results" in the
cargo-mutants documentation, which is very well-written. It gives
excellent suggestions for how to deal with missed mutants. Again,
these indicate potential gaps in your test suite. The documentation
discusses how to think about what to do, and I found it very helpful.
Then you should read about genres of mutants. It tells you
the kind of modifications that cargo-mutants does to your code. Apart
from changing individual operators to try to compute incorrect
results, it also does things like replacing whole function bodies to
return a different value instead. What if a function returns
Default::default() instead of your carefully computed value? What
if a boolean function always returns true? What if a function that
returns a HashMap always returns an empty hash table, or one full
with the product of all keys and values? That is, do your tests
actually check your invariants, or your assumptions about the shape of
the results of computations? It is really interesting stuff!
Future work for librsvg
The documentation for cargo-mutants suggests how to use it in CI, to
ensure that no uncaught mutants are merged into the code. I
will probably investigate this once I have fixed all the missed
mutants; this will take me a few weeks at least.
Librsvg already has the gitlab incantation to show test coverage for
patches in merge requests, so it would be nice to know
if the existing tests, or any new added tests, are missing any
conditions in the MR. That can be caught with cargo-mutants.
Hackery relevant to my tests, but not to this article
If you are just reading about mutation testing, you can ignore this
section. If you are interested in the practicalities of compilation,
read on!
The source code for the librsvg crate uses a bit of conditional
compilation to select whether to export functions that are used by the
integration tests as well as the crate's internal tests. For example,
there is some code for diffing two images, and this is used when
comparing the pixel output of rendering an SVG to a reference image.
For historical reasons, this code ended up in the main library, so
that it can run its own internal tests, but then the rest of the
integration tests also use this code to diff images. The librsvg
crate exports the "diff two images" functions only if it is being
compiled for the integration tests, and it doesn't export them for a
normal build of the public API.
Somehow, cargo-mutants didn't understand this, and the integration
tests did not build since the cargo feature to select that
conditionally-compiled code... wasn't active, or something. I tried
enabling it by hand with something like cargo mutants --package
librsvg -- --features test-utils but that still didn't work.
So, I hacked up a temporary version of the source tree just for
mutation testing, which always exports the functions for diffing
images, without conditional compilation. In the future it might be
possible to split out that code to a separate crate that is only used
where needed and never exported. I am not sure how it would be
structured, since that code also depends on librsvg's internal
representation of pixel images. Maybe we can move the whole thing out
to a separate crate? Stop using Cairo image surfaces as the way to
represent pixel images? Who knows!