diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..971c8964 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,1386 @@ +# Brandolini’s Reference + +> *A little learning is a dang’rous thing;* +> +> *Drink deep, or taste not the Pierian spring.* +> +> *There shallow draughts intoxicate the brain,* +> +> *And drinking largely sobers us again.* +> +> +> - Alexander Pope, 1711 +> + +This chapter serves as a helpful reference for developers, users and community members living in an Age of Bullshit Manufacture equivalent to the Cambrian Explosion. + +As we are surely only at the on-ramp of this trajectory, the chapter will continue to evolve, expand and be updated based on community feedback as events occur. + +## What The Reticulum License Is + +*To understand the legal reality relating to this section, see* [Void Grants](#void-grants). + +The [Reticulum License](./LICENSE) is the license under which RNS, the Reticulum reference implementation, has been published since **April 15, 2025**, in versioning effective from **0.9.4** and every release since. In practical terms, it covers all of “modern Reticulum”: The current wire format, the cryptographic machinery as it exists today (including the AES-256-based link encryption, ratchets, et cetera), and all protocol additions that distinguish the modern implementation from the earliest pre-1.0.0 beta formats. If an implementation speaks today’s Reticulum protocol, it is, in all relevant respects, built on Reticulum-licensed work. + +The license is a permissive license. It grants the full range of rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, free of charge; subject to three conditions, which are reproduced here verbatim: + +> * The Software shall not be used in any kind of system which includes amongst its +> functions the ability to purposefully do harm to human beings. +> * The Software shall not be used, directly or indirectly, in the creation of an artificial +> intelligence, machine learning or language model training dataset, including but not +> limited to any use that contributes to the training or development of such a model or +> algorithm. +> * The above copyright notice and this permission notice shall be included in all copies or +> substantial portions of the Software. + +### Why This License Exists + +Reticulum was not moved to a custom license casually or quickly. It was licensed under the MIT license for the greater part of its existence, and that served well for a long time. The change came when it became clear that no existing license expressed what the project needed, and that the two most commonly proposed alternatives would either say the wrong thing or say nothing useful at all. Three factors had primary influence on the situation: + +**The harm problem** + +Reticulum is a tool that was built, deliberately and at great cost, to empower people; to make communication something you own rather than something you are temporarily granted. It has also been, at various times, exactly what certain kinds of organisations would like to use to control people. This is the duality of any powerful tool. A permissive license could not, and cannot, say anything about that; MIT is silent on the question of whether the software may be used to build systems designed to harm human beings. The Reticulum License is not silent. It does not pretend that a license can stop an individual madman; it does assert, however, plainly and in enforceable terms, that corporations and organisations integrated into the legal system cannot consume this software for harm and then claim they never knew. The line is drawn by the creators of the tool, not by an external authority, and it is drawn deliberately. This is covered in more depth in the discussion of the ethics of the tool in the *Zen of Reticulum*. + +**The appropriation problem** + +The second factor was the machine-learning appropriation of the open-source commons. By 2025 that was no longer hypothetical: The commons was already being systematically ingested by corporate training pipelines, and the code, words, and creativity of the people who built it were being converted into synthetic systems designed to replace them. The license responds to this with an explicit condition: The software shall not be used in the creation of an AI, machine-learning, or language-model training dataset, nor in any use that contributes to the training or development of such a model or algorithm. + +It is important to understand what this condition does and does not do, which matters for what follows in this chapter. **The AI-training condition is not the legal basis for protecting the code from machine copying**. That protection *already exists*, in the oldest and most well-tested form of copyright law, and it applies regardless of any license (see [Copyright & The Two Legal Layers](#brandolinis-copyright-and-layers)). + +The AI-training condition addresses something *additional*: the appropriation of the code *into the models themselves*; the ingestion of human-made work as raw material for a synthetic replacement, and the use of that ingestion to fabricate “prior work” minefields, patent-troll material, and a wall of slop meant to bury and devalue the actual ecosystem. That danger was foreseeable; the licensing decision was made with full awareness of it. The events of 2026 have since demonstrated, in public and in detail, that the concern was not theoretical. + +**The sustainability problem** + +Reticulum has been developed and maintained for over a decade by a single person, supported by a small group of contributors and network-building users, without corporate backing, without VC funding, through several serious attempts at commercialization and takeover from both the corporate and the ideological side. The license is part of what makes that sustainable, and possible at all. + +It ensures that the specific, painstaking labor of the reference implementation cannot be hijacked to undermine the intent of the project, while leaving the protocol itself, the mathematical rules of how Reticulum works, dedicated to the public domain, where it belongs to humanity and can never be owned. Anyone can implement the protocol, provided they themselves invest the *actual* work and effort. What the license protects is the work, and the intent embodied in it. + +### On Freedom + +The most persistent mischaracterisation of the Reticulum License is that it is “more restrictive” than the licenses it replaced or than the GPL family. This is backwards, and I’ll state the comparison plainly, because the confusion is the foundation of a great deal of deliberately manufactured controversy examined later in this chapter. + +The GPL and AGPL are constructed around a single, self-referential axiom: that “free” is *defined by the terms of the license itself*, and that any use falling outside those terms is not free. In practice, this means the GPL restricts the freedom of **everyone** - you may not write, distribute, link, or (in some cases) even communicate with GPL-covered software without the entire arrangement being pulled under the same terms, which the licensor then controls. The restriction applies to 100% of users, including the ones building purely constructive things. + +The Reticulum License restricts the freedom of almost nobody. Its restrictions apply only to: + +* Those who wish to use the software in systems that purposefully harm human beings, and +* Those who wish to ingest the software into AI training pipelines. + +That is a restriction on a vanishingly small fraction of would-be users - the 0.0000001% - and it is a restriction they can characterise however they like, forever. The bickering is itself a signal that the licensing decision hit exactly the right target. + +Everyone else retains the full breadth of use, modification, distribution, and sale, with none of the viral encumbrance of copyleft. + +Both licenses contain moral axioms. The difference is that the Reticulum License states its axioms out loud: + +* *Intentionally restricting the way that millions of people use and build upon a foundational + communications technology* - **The mechanism of copyleft** +* *Intentionally restricting a small number of organisations from using the technology to + violently harm human beings* - **The mechanism of the Reticulum License** + +Which of these is more free? The answer is not a matter of committee approval. It is a matter of what the word “free” means to the people *whose freedom is at stake*. The question of whether “open source” requires the blessing of a particular licensing orthodoxy is examined in [Open Source Means Open Source](#brandolinis-opensource). + +### The Prediction, And What Happened + +When the license change was made and publicly discussed in 2025, the following was said, in public, about the machine-learning threat: + +> A generative system could be trained on the Reticulum codebase, and for extremely low cost +> be set to work spewing out millions of source repositories for all kinds of ridiculous +> “Reticulum-based programs”. This is already happening. You can find several examples of this +> on GitHub already. … the point of this kind of trolling is to establish as wide a base for +> “prior work” as possible. By doing that, a patent troll or IP abuser can create an immense +> minefield for real developers. + +This was written when the phenomenon was just beginning. It was not a guess; it was a description of a mechanism already in motion, in the specific context of Reticulum, by people who had already begun to appear around the project. + +Less than a year and a half later, the prediction has now been demonstrated, in public, exhaustively and to the letter. There are now roughly a dozen machine-generated “Reticulum implementations” of the same shape: fluent, marketing-heavy, some without attribution, and - in several cases - actively harmful to the network. The [Prns case](#brandolinis-prns) is an example documented in this chapter. The pattern that produced it (and the people, mechanisms, and the recycling of falsehoods behind the *wider* phenomenon) is examined in [A Movement Of A Dozen](#brandolinis-movement-of-a-dozen). + +The license was written, in part, so that when this happened, the community would not be defenceless. + +### What This Means For Other Implementations + +Two simple things must be kept separate: + +1. **The protocol is public domain.** The mathematical rules of Reticulum - addresses, + signatures, routing, the wire format as an idea - belong to humanity. A *genuine* clean-room + implementation of the protocol, written by human beings who reasoned it out themselves, is + free and welcome, and owes nothing to the Reticulum License. Nothing in this chapter is an + argument against implementing the protocol. On the contrary: More good implementations, + honestly made, are good for the network. +2. **The implementation is licensed.** Copying the reference implementation - by machine or + by silk-screen press - and modifying and redistributing the result, is + exercising rights granted by the license, and is therefore subject to its conditions: The attribution + notice, the harm condition, the AI-training condition. A copy that does not follow those + conditions is **not** licensed, and it is not “open source in spirit”; it is an unauthorized + derivative work, and therefore a copyright violation. + +The distinction is the same one the license itself makes, and it must be held firmly: An implementation that *speaks* Reticulum is exercising the public domain protocol, **if** it was truly created independently. An implementation that was *generated from* RNS, reproduced by a copy process, is a derivative of licensed work. + +### Copyright & The Two Legal Layers + +The exact legal structure is frequently muddied in public discussion; and in several cases deliberately. + +**Layer A - Copyright (license-independent)** + +Copyright does not depend on any license. A primarily machine-generated copy of a copyrighted work - a copy not accompanied by demonstrable, substantial, new human creative input - is a derivative work over which the copier holds no copyright whatsoever, and the reproduction of which, without the original author’s permission, is an infringement of the original author’s copyright. This is standard, well-tested law, and it applies with equal force under the MIT license, the GPL, or any other license, because it is not about the license at all; it is about who created what. A process that copies the reference implementation into a machine, produces a transformed derivative, and then claims “Copyright, [name of the process operator]” - with no human able to account for the creative decisions in the result - **is not** asserting a valid copyright over the result. They are openly asserting the absence of one, and reproducing someone else’s work without authorisation. This is probably the cleanest cut copyright violation one could imagine. + +**Layer B - License Conditions (Reticulum License specific)** + +Where a copy *is* a licensed derivative, the conditions of the Reticulum License apply: The copyright notice and permission notice must be included in all copies and substantial portions; the harm condition must be honoured; the AI-training condition must be honoured. A derivative that follows none of these is unlicensed *a second way over*. + +The two layers are often intentionally confused in public discussion - the AI-training condition is waved around as if the entire question of machine copying rested on it, when in fact machine copying of copyrighted work is a copyright violation that would exist even under the most permissive license ever written. The purpose of keeping the layers separate is not rhetorical flourish; it is that Layer A is old, settled law, and does not rely on any novel legal theory, while Layer B is specific to this license. Both matter. Neither is a substitute for the other. + +Layer B is the required mechanism for closing the loophole where the work is *first* ingested during model training into the weights of a model itself, which would make any resulting violations almost impossible to detect and enforce. + +### The “Clean-Room” Delusion + +I regularly receive mail or LXMF messages from people who proudly and happily proclaim that they have created a “clean-room” implementation of one of the software systems I maintain; RNS, Sideband, LXMF or others. The declaration is delivered with the flat certainty of someone who believes they have found the legal lock-pick that settles everything at once: Their production is independent, uncontaminated, and therefore free of any obligation to the work they copied, its license, or its author. The proclamation usually concludes with a request for blessing, or at least acknowledgment. The proclamation is, usually, also generated by an LLM. + +This is a delusion, and I’ll cut through it surgically. The word they here invoke as magic is attempting to do a great deal of work it was never able to bear. + +**What a clean room actually was** + +The legal “clean room” is not folklore, incantation, witchcraft or a claim a person gets to make about their own output. It is a very specific, institutionalized procedure that grew out of the hardware and software litigations of the 1980s, and it existed for exactly one purpose: **Convincingly proving the absence of copying in a court of law**. + +The canonical case was Phoenix Technologies and its 1984 reimplementation of the IBM PC BIOS. IBM’s BIOS was copyrighted, which meant that the entire PC-compatible industry depended on being able to show that a compatible BIOS had been written independently, and not from IBM’s code. Phoenix’s answer was a physical and procedural firewall: + +* One team, the “dirty room”, read the original code and produced written *functional specifications*: descriptions of what the BIOS did, not how IBM’s code did it. +* A second team, the “clean room”, consisted of engineers who had *never seen the original code at all*, and they wrote the new BIOS from those specifications alone. + +This obsessively documented, legally attested separation was not a preference or a willy-nilly show for a kindergarten; it was the entire legal point, and it had to be *solid*. If even one clean-room engineer had *glanced* at IBM’s code, the clone would have been contaminated, and the defense would shatter. + +The other landmark case was *Computer Associates v. Altai* (1992), in which Altai had copied CA’s scheduler code into its own product, and (upon being caught) hired outside counsel to run a genuine clean-room procedure: A programmer with no exposure to the original was brought in to rewrite the infringing modules from functional specifications prepared by the team that had seen the code. The court credited the good-faith effort precisely because it was done, as the carefully documented record showed, to the letter of the procedure. + +Bear in mind what this procedure entailed in practice, because this is the part the modern claimants never seem to have even *heard* of: Physical separation of teams, legal counsel managing the process, signed and notarised declarations of non-exposure, controlled specification documents that described *behaviour* and never *code*, months of work, and testing against the specification - not against the original, which the implementers were forbidden to consult. + +The people on the clean-room side of the wall did not just *claim* they had not read the code. Their non-exposure was institutionally guaranteed, obsessively documented, and legally attestable through every fart and sneeze of the process, because the entire point was that a court - hostile, adversarial, and entitled to discovery - would believe it. + +*That* is the process. “Clean-room implementation” is the name of a *certified procedure for proving independent authorship*. It is not a mood, a marketing label, or a property a person gets to declare about their own work. + +**The moronic inversion** + +Now consider what is actually being described when someone says: *“I created a clean-room implementation of Reticulum by feeding the source code into a machine.”* + +That sentence is the opposite of a clean room. Feeding a copyrighted work into a machine so that it reproduces and transforms the work is **the definition of copying**, and a clean room is the one procedure whose entire purpose is the demonstrated *absence* of copying. This process cannot demonstrate the absence of copying, because the process is *composed of* copying. The cleanest possible room has been replaced by the dirtiest possible room, and the dirt has been installed as the base feature. What these claimants have actually performed is a photocopy with extra steps, and the extra steps, far from cleaning anything, are simply steps that forge a certificate they believe the output has earned. + +**Why the word is deployed** + +The word “clean-room” is deployed because it sounds like what the speaker wishes were true. It carries the accumulated legal prestige of the 1980s and 1990s - the BIOS clones, the Altai credit - and it sounds like a certificate already issued: *Independent, original, unencumbered*, the work of a person who owes nothing. The claimants want that halo without the procedure: No law firm, no physical separation, no written specifications, no signed declarations, no months of process - just a laptop, a loop, and the word “clean-room” typed into a README. The word must do the work of the process it replaces, and the delusional replacement is the entire point. + +**The irony runs deep** + +The Reticulum protocol is public domain. Any human being can implement it - from the mathematics, from the documentation, from their own reasoning - and owe nothing whatsoever to the license, to the reference implementation, or to me. + +An honestly written implementation needs no incantations, no legal theater, and no special vocabulary; it simply *is* what it claims. It’s plain for everyone to see. **It’s also plain for everyone to see when you’re faking it**. The people who reach for the word “clean-room” are, without exception, the people who need it to create a fantasy - and the people who need that are precisely the people who cannot have it. If what you wrote were genuinely independent work on the public-domain protocol, you would not need to call it anything. The word is not a seal of independence. In this context it is a confession of copying, filed by the copier, in the confident belief that it says the opposite. + +## Open Source Means Open Source + +An objection regarding the “open source status” of RNS appears occasionally in variations, but always reduces to the same syllogism: + +1. “Open source” means *licensed under one of the licenses approved by the Open Source + Initiative (or, in other variants, compatible with GPL orthodoxy)*. +2. The Reticulum License is not on that list. +3. Therefore Reticulum is not open source, and anything built on it is illegitimate. + +The entire argument rests on the first premise, and the first premise is false. + +Open source is not a certification conferred by a committee. It is a description of a fact: The source code is available, and the rights to use, copy, modify, merge, publish, distribute, sublicense, and sell it are granted to everyone, free of charge. + +The Reticulum License does all of those things. It is, in every substantive respect that concerns the person who wants to use, study, modify, or build upon the software, **an open license**. What it adds - and what disqualifies it in the eyes of the orthodoxy - is two conditions on *who may do what with the original work*, not on what the *user* is allowed to do with it. + +The definition being wielded against Reticulum is not even a young one. It is, in essence, the Debian Free Software Guidelines written in 1997, adopted by the OSI in 1998, and treated ever since by certain people as if it had descended from a mountain on tablets. It is an approach that is close to three decades old. Being old is not itself a flaw - but being old is also not a proof of correctness, and the suggestion that the meaning of a word like “open” was settled for all time by a committee in the 1990s, and may never be revisited, is not a position rooted in reason. It is rooted in institutional inertia dressed as principle, maintained by those whose ideologies it serves. + +### What The Argument Is Actually Doing + +I would like to go into some detail about the rhetorical mechanism, because it is roughly the same mechanism that powers the rest of the campaign described later in this chapter. + +The orthodoxy’s argument is self-referential: *“open source means what we say it means, because we are the ones who define it.”* When the Reticulum License is measured against that definition and found wanting, the conclusion is presented as a property of Reticulum - when in fact it is *a property of the definition*. The definition is treated as neutral and authoritative - as some base fact of raw cosmology - and the license is treated as deviant. But the definition is no more neutral than the license is. It encodes a moral position, and that moral position is exactly the one that this project declines to take. + +Consider what the orthodoxy’s definition requires, in the case at hand. The OSI-based definition contains, in its ancestry, the Debian Free Software Guideline of “No discrimination against fields of endeavor”: The software must not restrict who may use it or for what purpose. Taken to its logical end, this means that open source, properly “certified”, must be equally available to those who build hospitals and those who build weapons, those who connect people and those who control them, those who create and those who ingest and replace. + +The orthodoxy presents this as neutrality. It is not neutrality; it is a moral position - one that says, in effect, that *harming human beings is a field of endeavor like any other, and software must not discriminate against it*. + +The Reticulum License takes a different position, and it has the honesty to state it in the license text: this software is for life, not for death; it is for people, not for the systems that would replace them. That is not a restriction on openness, nor on freedom. It is a restriction on *who may consume the work*, and it is a restriction the orthodoxy’s definition cannot express - which is why the orthodoxy must always attack the license as “not open source” rather than engage with what it actually does. + +### Who Is Restricted By Which License? + +The arithmetic is simple, so let’s do it out loud, because the orthodoxy’s framing inverts it every time. + +The GPL family imposes its conditions on **everyone**: You may not distribute, link, or - in the AGPL case - even *communicate with* GPL-covered software without your own work being pulled under the same terms. “Free” in this system is defined (self-referentially) *by the license’s own terms*; everything outside those terms is, by definition, unfree. The restriction applies to 100% of users. It applies to the hospital, the mesh community, the school, and the hobbyist with the same force it applies to anyone else. That is not freedom for everyone; it is a *specific moral architecture applied to everyone*, presented *as if it were the absence of one*. + +The Reticulum License imposes its conditions on a fraction of would-be users so small as to be practically unmeasurable: + +* Those whose intended use is to build systems that purposefully harm human beings, and +* Those whose intended use is to ingest the work into AI training pipelines. + +That is the entire list. Everyone else - the overwhelming majority, the community, the developers, the users, the downstream projects - receives the full, unrestricted rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, with none of the viral encumbrance of copyleft. + +So when the claim is made that the Reticulum License “is more restrictive” than the GPL, the claim is not merely wrong; it is the exact inverse of the truth. The GPL restricts the freedom of everyone, in the name of a specific ideology. + +The Reticulum License restricts the freedom of the harm-doer and the appropriator, and leaves everyone else free. The two approaches do not differ in whether they contain moral axioms - **all licenses do**. They differ in whether the axioms are stated openly, and in *whose* freedom they restrict. + +### The Consequences Of The “Not Open Source” Claim + +This would be a footnote debate if the mischaracterisation had no practical consequences. It has very large ones, and therefore this section exists. + +The claim that “Reticulum is not open source” is the foundation of the takeover narrative it so often accompanies. The sequence is always the same: + +* First, declare the reference implementation illegitimate (“not really open source”, “owned by one man”, “not a real community project”) +* Second, conclude that it is therefore acceptable - even necessary - to replace it. +* Third, present the replacement, which is (conveniently) often the speaker’s own machine-generated clone, as the legitimate heir. + +This is not speculation about motives; it is the documented structure of the campaign examined in [A Movement Of A Dozen](#brandolinis-movement-of-a-dozen). + +The “not open source” claim is the legal-ideological battering ram of that campaign. It is recycled, in article after article, in forum after forum, because it works on people who assume that a committee’s definition is the same thing as the truth. + +It is also worth stating the other obvious fact: None of these critics have ever shown that the Reticulum License restricts *them*. They do not build weapons. They are not training models on the codebase. They are free, in every practical sense, to use Reticulum exactly as they would under MIT or GPL. Their objection is not to a restriction on themselves; it is to the *mere existence* of a license that states a moral position they disagree with, or which they can use as leverage for a different goal entirely, and to the institutional fact that it does so outside *their* system of approval and control. The complaint is not that the license makes them unfree. The complaint is that the license is *free of them*. + +### The Distribution Argument + +A recurring companion claim is that RNS is not properly “distributed”, usually deployed as “it’s not packaged as a .deb” or “it’s not on package manager X”, with the implication that it is somehow unavailable or inaccessible, or hard to install on a given system. + +This is simply false, and it has been false for years. The reference implementation is available on practically every platform and architecture with a single command (`pip install rns`). It is packaged in the Arch User Repository, in NixOS, and in a range of other distribution channels, community-maintained and official. It can be installed, updated, and kept current *over Reticulum itself* - the network transports its own software updates. It is used on more than a hundred thousand devices worldwide, is embedded in over a hundred other packages and applications, and carries terabytes of traffic every day. + +The claim that Reticulum needs a `.deb` to be “really distributed” mistakes the mechanism for the goal. The goal is that people can obtain and update the software easily, everywhere, **on their own terms**, and distribute it themselves, both offline, online and over Reticulum with full cryptographic verification of the install packages, without any central infrastructure. + +That goal is met to an excellence that few software packages can speak of, and met in a way that does not pin the project’s release cadence to the review cycles of distribution maintainers, which is an achievement, not a bug. + +A project like RNS that updates continuously, sometimes daily, and has a track-record of shipping security updates mere hours after issues are discovered, would be crippled by packaging that makes every change wait months for approval. The distribution complaint is a strawman generated for the occasion. It has been answered, in public, many times; it is repeated anyway, because the people repeating it are not counting on facts - they are counting on the reader never having heard the answer. + +### On The Institutions, In Fairness + +None of the above is hostility toward the Open Source Initiative or the Free Software Foundation as institutions, nor toward the individuals who have dedicated decades of work to them. Their contribution to the world of software is **enormous**, and this document does not dispute it. What is disputed is a specific claim of authority: That “open source” is a term whose meaning is reserved to a committee’s approval, and that a license which does not submit itself to that approval is therefore not open. + +That claim of authority is not in Reticulum’s interest, and it is not in the interest of the people the movement claims to serve. The current legal and technological landscape - the machine-appropriation of the commons, the weaponisation of “prior work” generation, the erosion of human agency by synthetic systems - was not anticipated by the DFSG of 1997, and the institutions have not, as of this writing, produced *any* meaningful answer to it. The choice, as it was put at the time of the license change, is whether developers should sit back and wait for a solution from a committee that “may or may not ever materialize, before the entire foundation we stand on has been eaten away”. + +**Reticulum’s answer was to act**. If we had waited, it would have been too late. + +If an OSI-approved license existed that expressed the same constraints - and did not impose the far more severe restrictions of copyleft - the project would have used it. None such exists. That is not Reticulum’s failure. It is the measure of what the definition is missing. + +### What “Open” Means Positively + +For anyone who wants the positive statement rather than the rebuttal, Open Source, in this project’s understanding, means: + +* The source code is available, to everyone, without charge +* Everyone may use, copy, modify, merge, publish, distribute, sublicense, and sell the + software +* No one is discriminated against as a person - developer, user, community, or project +* The protocol itself is dedicated to the public domain, where no one can own it +* And the single, plainly stated condition of the license is that the work shall not be + consumed to harm human beings, or ingested to replace the humans who made it + +If that is not “open” by a definition written in the 1990s, then the definition is the thing +that has failed - not the software, and not the people who use it. + +**Open source means open source**. It was true before the committees existed to certify it, and it will remain true after they are gone. + +## Assistance Versus Machine-Substitution + +### False Dichotomy + +The public discussion around machine learning and software development has been derailed, by the loudest voices on both sides, into a farcical fight between “AI enthusiasts” and “AI haters”. + +> **Both positions are absolute caricatures.** + +> **The fight is beside the point in the ways that matters most.** + +It is not an accident, but a very conscious choice that the initial analysis of the Prns case examined herein, and this very chapter, were themself produced with the assistance of a machine-learning based generative system. + +Specifically, it was generated using `lc` managing a `Q8_K_XL` quant of `DeepSeek v4 Flash` running in the `llama.cpp` inference engine. The main context base used to stabilize, ground and inform the generative environment consisted of approximately 100,000 tokens of text material that I personally thought out and wrote (by hand), then archived and organized, over the last eight years. + +If you know my writing, and have a hard time discerning where this chapter is me directly, typing manually, and where it is the machine output, it is because of two things: Almost every line in this chapter was either directly edited by my hands on the keyboard or typed by me, and the text corpus that informed the process *is* genuinely me - my thoughts, written by me, over a period of years. + +The chapter was produced this way *deliberately and openly*, under a software framework I designed and wrote, with the human directing the inquiry points, flow of investigation, structure of the outputs, contents of every section, making the editorial decisions, reviewing the conclusions, painstakingly adjusting every line, and taking responsibility for the final claims presented, with the goal of reaching a higher level of synthesis and symbolic density than I could have achieved without that assistance. + +The tool was *used as tool*, both to structure and produce a complex chapter, and to inspect a repository so preposterous in size, commit velocity and nonsensical wording that it barred any purely human inquiry. + +As such, the position is hereby, by personal example and demonstration, stated clearly: + +* **Technological assistance is not the problem** + +* **It was never the problem** + +* **It is the opposite of the problem** + +The problems are *substitution* and *usurpation*: The perverse process in which the machine becomes the author of choices, and the human becomes the facade of software, while expecting “reciprocity” or recognition for deeds they never performed. + +### The Line + +The exact distinction can be reduced neither to how many lines of code a machine produced, nor who pressed the keys. The final distinction has to rest on **who, or what, the real agent of the work is**. + +* **Assistance** is when the human retains the full seat of agency: The human decides what to build, judges + what is correct, rejects what is wrong, understands what is shipped, and can answer for every single line of it. + The machine writes, suggests, drafts, accelerates *meaningfully* and within reason - but every choice that survives into the + final work is a choice the human made *consciously*, and understood - or grew to understand - the consequences of. + +* **Substitution** is when the machine *becomes* the agency: the machine decides what to build, + decides what is correct, iterates on its own errors, generates at a scale and speed no single + human can follow - and the human’s role is reduced to providing the name, the account, the + signature, and the marketing launch. + +> The Line can be stated as a single test, and this is the same test that has always separated authorship from couriership: **Can the person whose name is on the work answer for it fully?** Not “can they describe what it does” - can they account for why it is the way it is, line by line and decision by decision, and the history of how it came to be that way, under questioning, without machine assistance, including by people who know more than they do? + +If they cannot, they did not author the work. They wore it, or in more severe cases, they stole it. And a courier who claims authorship is not a writer; they are a fraud. + +### What assistance looks like + +Assisted work is recognisable, and recognisability is itself part of its value. It has the following observable properties: + +1. **The human can explain it.** Under examination, the author can say why this choice was + made, what was rejected, and what they verified. The ability to explain is not a luxury; + it is the very demonstration of authorship. On a large project with many contributors this is partial in + practice - no one can explain every line of a large codebase - but the *full capacity* must + exist between the authors and the *habit* must be visible. +2. **The human can, and does, reject machine output.** An author who has never rejected the machine’s output is not + an author, but an open drain. Rejection is not a stylistic flourish; it is the + mechanism by which any work attains Quality. A record of decisions, including reversals and rejections, + is a sign of agency. A record without rejection is a record of assent-by-default. +3. **The human’s judgment is directional.** The work contains the human’s actual choices; + things the machine would not have decided on its own, which the human can defend on their + merits. This directionality has many names in engineering: Design, architecture, taste, + judgment. Where it is absent, the work has the uniform, self-consistent texture of + something that was never doubted, and doubt is exactly what anything important requires. +4. **Provenance is not concealed.** Disclosure of how the work was made is not a legal + requirement in every jurisdiction; it is not even always a practical requirement. But it + is a *statement* that matters. A project that discloses its process - + including its use of machines - is telling the truth about the relationship between the + human and the work, and that is a property users *are* entitled to know. Concealment of + provenance is not a stylistic choice; it is deception, made by someone who knows what the + record would otherwise show. +5. **The human stands behind the failures.** When assisted work fails, the human can say: Yes, I + chose this, under these assumptions, here is why, here is what I got wrong, here is the fix. + That sentence is the entire contract between an author and the people who depend on their work. + A human who cannot say it - because the choices were never theirs - *has nothing to offer anyone*, and + is by definition entirely replaceable; anyone else could have pressed the same button. + +### What substitution looks like + +Substitution is equally recognisable, once the pattern is known: + +1. **Scope that no human could have authored.** Output that + structurally cannot have been the product of human authorship, review, and judgment, for + example when the volume exceeds any reasonable human capacity within the span of the project’s life. + When the review capacity and the output volume are incommensurable, the output was not + reviewed. It was generated, then forgotten, and the record was signed blindly. +2. **Uniform generation.** The work carries no trace of a human’s changing mind. No style + drift, no contested decisions, no “we tried X and it was wrong, so we did Y”. That is, *no + signs of actual development, growth and learning*. Instead, endless, self-referential + refactoring, renamed abstractions, and the same fluent register in every commit, + every document, every reply. A human’s history shows the wear of judgment. + Pure generation shows the superficial polish of its absence. +3. **Discovery by recursive regeneration.** When errors are found, they are found by the machine’s own + subsequent runs, not by human scrutiny - and the findings are recorded as planned + “reviews” and “alignments” rather than as the corrections they are. This is the tell: A + machine editing its own previous output, while the edit is recorded as if it were a + scheduled milestone. That’s not review. That’s a continuous generation loop revising itself, + with the attempt of an illusion-preserving voice-over. +4. **Laundered provenance.** Theatrical concealment machinery: Commit hooks that refuse + attribution of machine generation, contribution policies that declare machine output + “yours”, processes that scrub personal traces from the history, fake identities in the + contributor list. All of these have one function: To make the record say what the “author” + *wished* had happened, rather than what happened. A project that builds such machinery is + not making a record of its work; it is using automated software to manufacture one. +5. **Authorship by assignment.** The human’s name is on the work, but the human cannot + answer for it - because the human did not choose any of it, and knows it. The name is not a + signature of authorship; it is a *fraudulent claim of ownership* over something the claimant did not + make and cannot explain. In every field that has ever dealt with such claims - art, + literature, invention, journalism - *this has a name*. That **forgery** is now cheap in software + makes it no more forgivable. + +### Infrastructure Matters + +For a hobby project, the distinction between assistance and substitution is a personal matter. For infrastructure - code that other people’s communications, safety, and freedom run on - it is a matter of life and safety, and any statement about this must be entirely unapologetic. + +Infrastructure has one property that distinguishes it from almost all other software: While most of the people who depend on it cannot verify it themselves, **it must be verifiable, auditable and open to human inspection**, and be engineered in such a way that this is as frictionless and straight-forward as possible. + +The reference implementation of Reticulum was designed this way, and continues to make that goal a primary one. While it *is* a complex piece of software, with an intricate array of interlocking and moving parts, the core parts of RNS, the entire Reticulum protocol implementation, the transport logic, the cryptographic primitive interfaces, **is less than 15,000 lines of code**. That line count even includes the rather extensive comments, incredibly detailed logging facilities and other choices that makes the code easy to read and understand for humans, and easy to operate, verify and debug. It took real dedication, and *a lot* of hard work to achieve that. + +Exactly because not *everyone* can do this, it is a fundamental necessity for infrastructure software that it is designed and authored so that *as many as possible can*, and that the *chain of accountability* - who made it, who reviewed it, who answers for it - is held intact at every link. That chain is not decoration. It is the entire mechanism by which normal users decide to trust a system they cannot fully verify. The transparent foundations and the chain combined *is* the verification for most users. + +Substitution breaks the chain both at the foundations, and at its load-bearing link: The human at the top can no longer answer, because they were never the maker. Unfortunately, the chain does not always fail visibly; often it fails silently, at the exact moment a question goes deep, or when routing fails subtly at a critical moment. + +For the user, the result is not a project with a normal and humanly flawed author - it is a project *with no author at all*; a signature with no substance behind it, a name that cannot be held to account, and a body of work that nobody on earth can (or wants to) explain, defend, or fix in a crisis. + +### The Fluency Trap + +It is worth understanding, briefly, why substitution is so attractive and so dangerous at once. Machine-generated output is fluent. It is confident, well-structured, and terminologically *self-consistent*. At the surface, and from the perspective of someone outside a given craft, it is indistinguishable from the output of a knowledgeable human. Fluency of this kind can be a useful property: It makes assisted work fast. But fluency is *not* understanding. It is the *minimal conformal surface* of understanding. + +The danger is that the surface is exclusively where the substituter invests; for the simple reason that the surface is where most of the desired audience looks, and what yields attention to the project. + +A human who can tell the difference uses the tool well. A human who cannot is being deceived through means they cannot detect from inside, namely through their own inability to account for the limits imposed by what they do not know. + +This is why the most important quality for anyone working with systems like Reticulum is not speed, and not vocabulary, but the oldest engineering virtue there is: The honest, uncomfortable, terrorizing knowledge of **what you do not know**. The substitute *never* has it. The substitute’s operator, *if* they ever had it, loses it precisely the moment they accept the fantasy of the substitution process. + +The tool is not the hazard, plain old human nature is. The tool is a mirror, and mirrors - as has been observed for rather longer than software has existed - show the truth only to those willing and yearning to see their own shortcomings. + +### Disclosed Assistance Or Laundered Generation + +The contrast at the centre of this entire discussion can be made clearer with two examples, both of which are publicly accessible, both produced in the same year, by people using the same class of tools. + +The first is this chapter. It was produced with machine assistance, openly: the structure was directed by the human, the material was assembled with the tool’s help, every conclusion, every line, every slight nuance of meaning and semantics was examined, edited, and accepted or rejected by the human, and the process described publicly - including the precise characteristics of the technological assistance framework used. The human can answer for every claim in these documents, because the human made the decisions the claims rest on. + +The second is the project examined in [the Prns case](#brandolinis-prns). It was produced by a machine, at a volume no human could review, and the authorship record was engineered to erase the machine’s role: A commit hook that refuses attribution of machine generation, a contribution policy declaring machine output the human’s own, a fictitious contributor identity, 637,000 lines of unreviewed code. The human cannot answer for the code, because the choices were never made by a human - only the conformal surface of the presentation was. + +The same tool class. The same technology. Two diametrically opposed relationships to truth and responsibility. **The difference is not the tool**. The difference is the presence or absence of the human as the agent of the work - and the honesty or concealment with which that relationship is recorded. + +Assistance leaves the human as the agent and the commons as the source from which the human works and can grow. Substitution removes the human from the loop and converts the commons into fuel for the thing that seeks to replace them, or usurp their work for the profit of the few, human atrophying in the process. + +### The License In This Context + +The Reticulum License, examined in [What The Reticulum License Is](#brandolinis-what-the-license-is), draws the same line, at the level of the law. Its AI condition does not forbid the use of machine-learning technology to *assist* development - no reading of the license could support that, and no one associated with this project has ever claimed so. What the condition forbids is the *appropriation of the work into the machine itself*: The ingestion of the commons as raw material for synthetic replacement, and the concealed fabrication of “prior work” that would bury the real thing. + +As also noted in [Copyright & The Two Legal Layers](#brandolinis-copyright-and-layers), plain old copyright law already protects against the case where a process copies the reference implementation into a machine, produces a transformed derivative, and then claims “Copyright, [name of the process operator]”, with no human able to account for the creative decisions in the result. That is simple, petty theft, as it always has been. + +### The General Principle + +In these regards, the position of this project can be codensed to something relatively concise: + +* Machine assistance in human learning, development, and creation is accepted and useful. + It is not a shameful secret; but it *is* a tool that needs knowledge, training, understanding, + and great care to use. It should not make anything easier or more fun, it should make the + results better, more carefully considered, and arrive at *higher levels of synthesis*, not + produce endless streams of code churn. +* The line is crossed when the human stops being the agent of the work. When *any* output is + accepted that the human cannot explain, produced at a scale the human cannot review, or filed under a record + where the human has arranged to conceal the fact. +* The line is crossed, when a human claims authorship of work they cannot + answer for or has usurped. Credit follows the ability to answer. It has always worked that way, and + machines do not change the rule - they only make it cheaper and more tempting to break. +* The people who depend on infrastructure have the right to know which side of the line + the code they run was made on. That knowledge is the only verification most of + them will ever be able to perform. + +Use assistance, by all means, *and learn*, but don’t substitute. And never sign what you cannot answer for. + +Somewhere, within the general shape of the conceptual framework outlined in this section, or realistically, a more refined variant of it, I do believe there is the *potential* of the *beginning* of a constructive outcome to the immense challenge we are faced with as a species in regards to these problems. + +At the same time, I reserve my right to revert that position to Butlerian Jihad without prior notice. We are on a knife’s edge, and you know it just as well as I do. + +## Void Grants: Legal Foundations of Machine-Generated Code + +A grant of rights is only as real as the rights behind it. A license conveys what its issuer holds, and nothing more. A derivative may be distributed only under whatever license covers what it took. And over a work that a machine originated, no human holds anything at all. + +Each of these statements is a matter of settled statute and case law, and this section sets out the authorities. The conclusions they support are: + +1. A software implementation generated from a licensed work by a machine, published under its operator’s claimed copyright and license, **conveys rights the operator never possessed**. +2. **Its grant is void**. The projects, products, and promises built upon such grants stand on nothing. A field of void grants is a minefield for everyone who crosses it. + +This section is a general examination of copyright law as it applies to machine-generated code. It is not legal advice. + +### I. The Foundational Statute: Translation Is Copying + +The starting point is the statutory definition of the class of works at issue. Title 17, United States Code, section 101 provides the definition of a derivative work: + +> A “derivative work” is a work based upon one or more preexisting works, such as a *translation*, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or *any other form in which a work may be recast, transformed, or adapted*. + +Section 101 further provides that *“the terms ‘including’ and ‘such as’ are illustrative and not limitative”*. As such, the list is a list of *examples*, and the very first example is translation. The definition also reaches, in its own words, *“any other form in which a work may be recast, transformed, or adapted”*. + +The exclusive right at issue is defined in section 106: + +> Subject to sections 107 through 122, the owner of copyright under this title has the exclusive rights to do and to authorize any of the following: +> (1) to reproduce the copyrighted work in copies or phonorecords; +> (2) to prepare derivative works based upon the copyrighted work; +> (3) to distribute copies or phonorecords of the copyrighted work to the public by sale or other transfer of ownership, or by rental, lease, or lending; + +Violation of any of these rights is infringement. 17 U.S.C. § 501(a). + +Taken together, the provisions yield a construction that is difficult to improve upon and impossible to escape: + +1. **A port is a translation.** A work that takes a program written in one language and from it produces a program written in another language, implementing the same behavior, is a translation of the original - whatever mechanism performed it, and however the surface presentation differs. +2. **A translation is a derivative work.** Section 101 says so, explicitly. +3. **Preparing a derivative work is the copyright owner’s exclusive right.** Section 106(2) says so explicitly. A derivative work prepared without authorization, or outside the scope of any authorization, infringes that right. + +The common objection - “the code is in a different language, so it is completely different” - is not a legal argument; it is the definition of what the statute already classifies. + +Translation *is the paradigm* of derivative authorship, not an exception to it. If translating a work without permission was a defense, the derivative-work right would be meaningless; every infringing adaptation would simply need to be “different enough” to count as a translation of its source. + +Nor does the identity of the translator change the analysis. The statute asks whether the work is “based upon” a preexisting work. It does not ask who or what performed the translation. A machine that ingests a licensed work and reproduces a translated transformation of it has performed mechanical translation; the output is a derivative of the ingested work, and the law governing derivative works applies to it exactly as it applies to a translation made by hand. + +### II. Ideas Are Free, Expressions Protected + +The second foundation is the distinction between what a work *is* - its ideas, its processes, its systems - and the *expression* in which those ideas are embodied. The distinction is codified in section 102(b): + +> In no case does copyright protection for an original work of authorship extend to any idea, procedure, process, system, method of operation, concept, principle, or discovery, regardless of the form in which it is described, explained, illustrated, or embodied in such work. + +The principle is older than the statute, and its application to software is settled. An author may own the particular code in which a method is expressed; the method itself, the process, the algorithm, belongs to no one - because *“the sine qua non of copyright is originality”* (*Feist Publications, Inc. v. Rural Telephone Service Co.*, 499 U.S. 340, 345. 1991). And ideas are not original to anyone in particular, *Baker v. Selden*, 101 U.S. 99 (1879), established the line: Copyright in a book describing a system does not prevent others from practicing the system. + +Applied to a communications protocol, the structure is clean: + +--- + +**An implementation of a public-domain protocol, honestly reasoned and written by humans, is welcome and unencumbered, and owes nothing to any license. An implementation generated from a licensed implementation is a derivative of licensed work, subject to its conditions and to the ordinary copyright of its source.** + +--- + +The public-domain status of the protocol’s ideas changes nothing about the copyright in an implementation’s expression. A person who copies an implementation - by machine or by hand - cannot defend the copying by pointing to the protocol, because the protocol covers the ideas, not the symbols in which someone expressed them. + +A further misconception can be dismissed here; the recently popularized “clean-room” claim about the absence of copying. A [clean-room](#brandolinis-cleanroom-delusion) is a not a magic label achievable by LLM, but a specific, institutionalized procedure for proving to a court that copying did not occur: Physically separated teams, written functional specifications, attestable non-exposure, and no access to the original by the implementers (*Altai*, 982 F.2d at 709–11). + + *“I created a clean-room implementation by feeding the original source code into a machine”* attempts to *claim* the certified, legally established procedure for proving the absence of copying by describing, in the same breath, a process **composed entirely of copying**. The word is deployed because the procedure it names is what the claimant would *need to have happened*. + +### III. Machine Output Has No Author + +The third foundation is the human authorship requirement. It is settled at both levels of the federal courts and in the Copyright Office’s administering practice. + +In *Thaler v. Perlmutter*, the district court held that *“copyright law protects only works of human creation,”* and that *“human authorship is a bedrock requirement of copyright”* (687 F. Supp. 3d 140, 146, D.D.C. 2023). On appeal, the United States Court of Appeals for the District of Columbia Circuit affirmed, holding that the Copyright Act *“requires all eligible works to be authored in the first instance by a human being”* (No. 23-5233, D.C. Cir. Mar. 18, 2025). + +The requirement traces to the ordinary meaning of the statutory term. In *Burrow-Giles Lithographic Co. v. Sarony*, the Supreme Court defined an “author” as *“he to whom anything owes its origin; originator; maker; one who completes a work of science or literature”* (111 U.S. 53, 57–58, 1884), and more recently described the author as *“the person who translates an idea into a fixed, tangible expression entitled to copyright protection”* (*Community for Creative Non-Violence v. Reid*, 490 U.S. 730, 737, 1989). + +--- + +**A machine does not owe expression its origin; it reproduces it. No court has recognized copyright in material created by non-humans, and the courts that have addressed the question have rejected it. If you create by machine generation, you do not own the output.** + +--- + +The Copyright Office’s registration guidance applies the requirement to generative systems in terms that are directly on point. The Office asks: + +> whether the “work” is basically one of human authorship, with the computer [or other device] merely being an assisting instrument, or whether the traditional elements of authorship in the work (literary, artistic, or musical expression or elements of selection, arrangement, etc.) were actually conceived and executed not by man but by a machine. +* *Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence*, 88 Fed. Reg. 16190, 16192 (Mar. 16, 2023) + +And it states the consequence: *“If a work’s traditional elements of authorship were produced by a machine, the work lacks human authorship and the Office will not register it”* (*Id.*). + +On the role of prompts, the Office is equally explicit: when a system receives a prompt and produces a work in response, *“these prompts function more like instructions to a commissioned artist - they identify what the prompter wishes to have depicted, but the machine determines how those instructions are implemented in its output”* (*Id.*). + +The agency applied this standard and excluded machine-originated material from registration in the leading administrative case. In *Zarya of the Dawn* (Cancellation Decision, Feb. 21, 2023, Registration No. VAu001480196), the Office cancelled registration of images generated by the Midjourney service, holding that *“it was Midjourney-not [the author]-that originated the ‘traditional elements of authorship’ in the images”*, while preserving protection for the human-authored text and the human selection and arrangement of the work. + +The Copyright Office’s 2025 report on AI copyrightability reaches the same conclusion: + +> Based on the functioning of current generally available technology, prompts do not alone provide sufficient control. +* U.S. Copyright Office, *Copyright and Artificial Intelligence, Part 2: Copyrightability*, at iii (Jan. 29, 2025) + +The report’s analysis is explicit: *“The Office concludes that, given current generally available technology, prompts alone do not provide sufficient human control to make users of an AI system the authors of the output. Prompts essentially function as instructions that convey unprotectible ideas”* (*Id.* at 18). + +Its guiding distinction is stated plainly: *“The use of AI tools to assist rather than stand in for human creativity does not affect the availability of copyright protection for the output”* while *“Copyright does not extend to purely AI-generated material, or material where there is insufficient human control over the expressive elements”* (*Id.* at iii). + +The boundary is therefore not “AI or no AI”. It is *assistance or substitution*: Whether a human exercised sufficient creative control over the expressive elements and can answer for them, or whether the machine originated them and the human merely supplied instructions and a signature. That is a question of fact in each case, determined from the record of how the work was made. + +Two facts follow, and stated together, they form the base legal reality: + +1. **A work whose expressive elements were originated by a machine contains no valid new copyright: It has no human author. To the extent that the same work reproduces a preexisting copyrighted work without explicit license, it is at the same time an unauthorized derivative. It is unowned for anything new it contains, and unlicensed for everything taken.** +2. **Its operator therefore holds no copyright in it and no grant over it - and a person who holds neither copyright nor grant can convey neither.** + +The first fact makes the work **unownable** by its operator. The second makes it infringing against its source. Neither replaces the other: + +* The absence of copyright in machine output does not make the output free for anyone to take; it makes it unowned. +* This is a different thing entirely, especially when what it contains is someone else’s expression. + +### IV. License Conditions Bound the Grant + +The fourth foundation governs what a license *is*. A copyright owner may grant permission to use the work on conditions. The conditions define the scope of the permission. Use outside the scope is use that was never authorized. + +In *Jacobsen v. Katzer*, 535 F.3d 1373 (Fed. Cir. 2008), the Federal Circuit held that the conditions of an open-source license are *conditions of the copyright license itself*, not mere contractual promises, and that a licensee operating outside them is an infringer: + +> Copyright holders who engage in open source licensing have the right to control the modification and distribution of copyrighted material. + +> The choice to exact consideration in the form of compliance with the open source requirements of disclosure and explanation of changes, rather than as a dollar-denominated fee, is entitled to no less legal recognition. + +> It is outside the scope of the [license] to modify and distribute the copyrighted materials without copyright notices and a tracking of modifications from the original computer files. +* *Id.* at 1381–82 + +The doctrinal mechanism is settled: *“A copyright owner who grants a nonexclusive license to use his copyrighted material waives his right to sue the licensee for copyright infringement”* within the scope of the license. If, however *“the licensee acts outside the scope, the licensor can bring an action for copyright infringement”*: An act outside the granted scope **is infringement** (*Sun Microsystems, Inc. v. Microsoft Corp.*, 188 F.3d 1115, 1121, 9th Cir. 1999; *Graham v. James*, 144 F.3d 229, 236, 2d Cir. 1998; *S.O.S., Inc. v. Payday, Inc.*, 886 F.2d 1081, 1087, 9th Cir. 1989). + +Whether a given license term is a condition of the grant or a mere covenant is determined from the license’s own language; conditions that limit what may be copied, modified, and distributed - the attribution terms, the notice terms, the modification-tracking terms, the field-of-use terms - are the boundaries of the copyright grant (*MDY Industries, LLC v. Blizzard Entertainment, Inc.*, 629 F.3d 928, 940, 9th Cir. 2010). + +Three consequences follow for the analysis at hand. They are not hypothetical. + +**First, the conditions are measured at the moment of copying** + +A work is licensed under whatever conditions applied when the reproduction, adaptation, and distribution occurred. There is **no** period in which copying a licensed work is “free” because the copy was made by a machine; the machine is the *licensee’s tool*, and the licensee is bound by the conditions regardless. A derivative generated without satisfying the conditions - without the attribution, without authorization for the manner of use - was never within the scope of the license, from the first instant of its existence. + +**Second, breach does not restore rights that never attached** + +The district court in *Artifex Software, Inc. v. Hancom, Inc.*, No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017), analyzing the GPL’s termination provisions, observed that *“the language of the GPL suggests that [the licensee’s] obligations persisted beyond termination of its rights to propagate software using Ghostscript,”* because the source-code obligation recurs each time a covered work is conveyed. The same structure operates a fortiori where a derivative was produced *outside* the license entirely: No grant ever attached, and no subsequent event creates one. + +**Third, the settled conditions are the enforceable core** + +The attribution and notice conditions rest on the settled doctrine above. Novel conditions (restrictions on field of use, restrictions on how the work may be consumed) are enforceable as conditions of the grant when clearly drafted, but their enforcement history is thinner. The argument that a derivative is unlicensed does *not* depend on the novel conditions being vindicated; it needs **only** the settled ones, and the ordinary law of derivative works, to stand. + +### V. The Void Grant + +The preceding sections assemble into a single structure. Let us apply it to an example situation: + +* A project presented as an independent implementation of a protocol; “ground-up”, “from scratch” or “clean-room” work. +* The actual history shows continuous, machine-mediated ingestion of a licensed reference implementation. +* The output is generated at a scale no human could produce or review, with the provenance of the process obscured. + +**Step One: The derivative** + +The project’s output is a translation of the licensed implementation: A derivative work, produced by a copy process. 17 U.S.C. §§ 101, 106(2). Preparing it without authorization infringed from the first moment of its existence. *Id.* § 501(a). + +**Step Two: The license** + +The derivative was produced outside the conditions of the license; without the notices, without the attribution. The license never attached (*Jacobsen*, 535 F.3d at 1381–82). + +**Step Three: Authorship** + +The expression was originated by a machine. No human can account for its creative decisions, and no human authored it. It contains no valid new copyright (*Thaler*, 687 F. Supp. 3d at 146; No. 23-5233, D.C. Cir. 2025; 88 Fed. Reg. at 16192). + +**Consequence: Void Grant** + +The statute supplies the consequence. Section 103(a) provides: + +> The subject matter of copyright as specified by section 102 includes compilations and derivative works, but protection for a work employing preexisting material in which copyright subsists does not extend to any part of the work in which such material has been used unlawfully. + +And section 103(b) provides that copyright in a derivative work *“extends only to the material contributed by the author of such work.”* The legislative history states the point without ambiguity: *“An unauthorized translation of a novel could not be copyrighted at all”* (H.R. Rep. No. 94-1476, at 57, 1976). + +In our example, the operator of the derivative’s copy process decides to assert copyright over the output, and licenses it to the world under terms of the operator’s choosing, for example the Apache License. + +But the operator holds no copyright in machine-originated content (section III) and no license over the source from which it was derived (sections I and IV). + +For the derived material, the operator’s copyright claim **is an assertion of a right that never existed**. The material was used unlawfully, and section 103(a) withholds protection from *every* part of the work in which it appears. For the machine-originated remainder, the operator holds no copyright either, for lack of any human author. + +The operator’s license to the world is a promise the operator had no power to make. Every person who receives the work believing they received a valid grant has received **a void grant**, and stands, as a matter of settled law, in the position of a downstream user of an unauthorized derivative, whatever they were told at the time. + +This is a cascading consequence, and it is why the pattern is a hazard. No combination of self-granted licenses - “MIT,” “Apache,” “public domain,” anything at all - can transfer rights the operator never held. Every downstream project, product, or deployment built on the derivative is built on unlicensed reproduction of a third party’s work, whether or not it knew, whether or not it was told, and whether or not the marketing was plausible. + +The longer the derivative circulates unexamined, the more it becomes embedded, forked, vendored, depended upon, and the more expensive its correction becomes for everyone who trusted it. A field of superficially real projects, repositories, and licenses that **in reality confer nothing on anyone who relies on them is a minefield**, in the most precise sense the law allows: The rights they purport to grant *were never possessed*. + +The law defines what may be asserted, not what will be. The copyright owner may choose whether and how to assert these rights, and at what point in time. The exposure exists regardless, and for *every* downstream that trusted the void grant. This is the scope of the hazard that the conduct exemplified here produces. + +### VI. Fair Use Does Not Rescue This Pattern + +Every defendant raises fair use. It is an essential and important limitation in the service of free speech, accountability, criticism, education and other important domains. Therefore, it must be considered, and in the case exemplified here, it fails. + +Fair use is a limitation on the exclusive rights, evaluated case by case under four factors: The purpose and character of the use; the nature of the copyrighted work; the amount and substantiality of the portion used; and the effect of the use on the potential market for or value of the work (17 U.S.C. § 107). + +On the first factor, the governing standard is *Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith*, 598 U.S. 508 (2023), in which the Supreme Court held that: + +> In sum, the first fair use factor considers whether the use of a copyrighted work has a further purpose or different character, which is a matter of degree, and the degree of difference must be balanced against the commercial nature of the use + +The question is whether the use serves a further purpose, not whether the surface changed. A derivative that exists to serve as the same thing as the original, marketed to the people who would otherwise use the original, has not acquired a further purpose by being translated; the surface changed, the function did not, and the use is commercial. + +The remaining factors resolve the same way. Source code is expressive creative work, not bare fact. The pattern under examination copies the whole; a complete implementation, ingested and translated in its entirety. And the market effect is the decisive factor, because it is engineered: A derivative marketed as a drop-in replacement for the work it was copied from is not a complement to the original’s market, it is a substitute for it. The Supreme Court has long held that use of a work to satisfy the market demand for the original is the paradigm of an *unfair* use (*Harper & Row, Publishers, Inc. v. Nation Enterprises*, 471 U.S. 539, 566–67, 1985). + +The one case that is always raised in response, *Google LLC v. Oracle America, Inc.*, 593 U.S. 1 (2021), holds less than it is believed to. The Court there assumed *“for argument’s sake, that the material was copyrightable”* and held *“that the copying here at issue nonetheless constituted a fair use”* (*Id.* at 11). + +The material in question was a thin slice of *declaring code*, which the Court found sits, *“if copyrightable at all, further than are most computer programs (such as the implementing code) from the core of copyright”* (*id.*), in a use that built a new platform for a new environment, with the copier **having written the vast majority of its own code**. By comparison: A wholesale translation of an entire implementation, marketed as a substitute for it, is **not** that case; it is the other end of every factor. + +The valuable zones of fair use remain, and they are important. **Commentary and criticism**, quoting from a work to review, discuss or criticize it. **Teaching and scholarship**, explaining concepts and quoting excerpts, is its traditional beneficiary. + +### Conclusion + +The law is neither obscure nor new. The conclusion it yields can now be stated: + +* A machine translation of a protected implementation **is a derivative work**, and an unauthorized derivative **is an infringement**, whatever language it speaks and whatever machinery produced it. +* A work whose expression a machine originated has no human author, no valid new copyright, and without valid copyright **no license can be granted on it**. +* § 103 withholds protection from every part of a derivative in which protected material was used unlawfully. A license is a grant with conditions, and a derivative made outside the conditions **never received a grant**. +* A person who holds no copyright and no grant **can convey neither**, and *every* downstream consumer who received from them received a **void grant**. + +This is a *catastrophic* failure state for all who want to create things good and useful: The projects that inherit only void grants and liability believing they have inherited foundations, the users who depend on code that no one on earth can answer for, the honest builders whose work is buried under a field of plausible-looking impostors. + +### Sources and Authorities + +Statutory references are to Title 17, United States Code. Case citations are to the official or generally cited reporters. Online links are for reference only. Section numbers refer to the sections in which each authority is principally relied upon. + +**Statutes** + +* [17 U.S.C. § 101 (definitions: “derivative work,” “including,” “publication”) - I, II](https://www.law.cornell.edu/uscode/text/17/101) +* [17 U.S.C. § 102(b) (idea/expression) - II](https://www.law.cornell.edu/uscode/text/17/102) +* [17 U.S.C. § 103(a)–(b) (derivative works employing unlawfully used preexisting material) - V](https://www.law.cornell.edu/uscode/text/17/103) +* [17 U.S.C. § 106(1)–(3) (exclusive rights: reproduction, derivative works, distribution) - I](https://www.law.cornell.edu/uscode/text/17/106) +* [17 U.S.C. § 107 (fair use) - VI](https://www.law.cornell.edu/uscode/text/17/107) +* [17 U.S.C. § 501(a) (infringement) - I, V](https://www.law.cornell.edu/uscode/text/17/501) + +**Judicial decisions** + +* [\*Jacobsen v. Katzer\*, 535 F.3d 1373 (Fed. Cir. 2008) - IV, V](https://www.casemine.com/judgement/us/5914b290add7b04934760a54) +* [\*Sun Microsystems, Inc. v. Microsoft Corp.\*, 188 F.3d 1115 (9th Cir. 1999) - IV](https://law.justia.com/cases/federal/appellate-courts/F3/188/1115/629501/) +* [\*Graham v. James\*, 144 F.3d 229 (2d Cir. 1998) - IV](https://caselaw.findlaw.com/court/us-2nd-circuit/1011522.html) +* [\*S.O.S., Inc. v. Payday, Inc.\*, 886 F.2d 1081 (9th Cir. 1989) - IV](https://law.justia.com/cases/federal/appellate-courts/F2/886/1081/19091/) +* [\*MDY Industries, LLC v. Blizzard Entertainment, Inc.\*, 629 F.3d 928 (9th Cir. 2010) - IV](https://law.justia.com/cases/federal/appellate-courts/ca9/09-15932/09-15932-2011-02-25.html) +* [\*Artifex Software, Inc. v. Hancom, Inc.\*, No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017) (settled; dismissed with prejudice Jan. 2018) - IV](https://storage.courtlistener.com/recap/gov.uscourts.cand.305835/gov.uscourts.cand.305835.54.0_1.pdf) +* [\*Thaler v. Perlmutter\*, 687 F. Supp. 3d 140 (D.D.C. 2023), aff’d, No. 23-5233 (D.C. Cir. Mar. 18, 2025) - III, V](https://www.bitlaw.com/source/cases/copyright/Thaler-Perlmutter-Dct.html) +* [\*Burrow-Giles Lithographic Co. v. Sarony\*, 111 U.S. 53 (1884) - III](https://supreme.justia.com/cases/federal/us/111/53/) +* [\*Community for Creative Non-Violence v. Reid\*, 490 U.S. 730 (1989) - III](https://supreme.justia.com/cases/federal/us/490/730/) +* [\*Feist Publications, Inc. v. Rural Telephone Service Co.\*, 499 U.S. 340 (1991) - II](https://supreme.justia.com/cases/federal/us/499/340/) +* [\*Baker v. Selden\*, 101 U.S. 99 (1879) - II](https://supreme.justia.com/cases/federal/us/101/99/) +* [\*Computer Associates International, Inc. v. Altai, Inc.\*, 982 F.2d 693 (2d Cir. 1992) - II](https://law.justia.com/cases/federal/appellate-courts/F2/982/693/137252/) +* [\*Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith\*, 598 U.S. 508 (2023) - VI](https://www.supremecourt.gov/opinions/22pdf/21-869_87ad.pdf) +* [\*Google LLC v. Oracle America, Inc.\*, 593 U.S. 1 (2021) - VI](https://supreme.justia.com/cases/federal/us/593/18-956/) +* [\*Harper & Row, Publishers, Inc. v. Nation Enterprises\*, 471 U.S. 539 (1985) - VI](https://supreme.justia.com/cases/federal/us/471/539/) + +**Administrative and policy authorities** + +* [\*Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence\*, 88 Fed. Reg. 16190 (Mar. 16, 2023) - III](https://www.federalregister.gov/documents/2023/03/16/2023-05321/copyright-registration-guidance-works-containing-material-generated-by-artificial-intelligence) +* [\*Zarya of the Dawn\*, U.S. Copyright Office (Cancellation Decision, Feb. 21, 2023), Registration No. VAu001480196 - III](https://www.copyright.gov/docs/zarya-of-the-dawn.pdf) +* [U.S. Copyright Office, \*Copyright and Artificial Intelligence, Part 2: Copyrightability\* (Jan. 29, 2025) - III](https://www.copyright.gov/ai/Copyright-and-Artificial-Intelligence-Part-2-Copyrightability-Report.pdf) +* [H.R. Rep. No. 94-1476 (1976) - V](https://law.resource.org/pub/us/works/aba/ibr/H.Rep.94-1476.pdf) + +## Evaluating a Reticulum Implementation + +### The Intention Of This Guide + +Very few user of network infrastructure can verify the software they run. This is true of the reference implementation as well, and it is precisely why it was engineered the way it was: the entire Reticulum protocol implementation - the transport logic, the cryptographic interfaces, the routing - is less than 15,000 lines of code, including its extensive comments and detailed logging. The reference is *designed* to be readable by a human in a reasonable sitting. That is a deliberate decision, and it is the standard against which every other implementation should be measured: An implementation that asks for trust while being structurally unreadable is asking for the absurd. + +Because most users cannot verify the code directly, the evaluation of the *project* is the evaluation of the software. The framework below exists so that this evaluation can be performed in minutes, by anyone, without expertise - and so that each new “implementation” does not require the kind of full investigation that would otherwise be if not impossible, prohibitevly expensive. + +### Two Questions That Resolve Most Cases + +Other considerations in this guide is further corroboration. These two questions allow you to decide the case quickly in most instances, and they should be asked first. + +**Question 1: Does this speak the protocol, or was it just generated from the reference?** + +The copyright and license realities, described in [What The Reticulum License Is](#brandolinis-what-the-license-is), is the legal foundation of this distinction. The protocol is public domain: A *genuine* [clean-room](#brandolinis-cleanroom-delusion) implementation, reasoned out and written by humans, is free and welcome, and owes nothing to any license. But an implementation that was *directly generated from* the reference - reproduced by a copy process, whether manually or through a machine or software - is a derivative of the licensed work, and is subject to both the license’s conditions, and to the ordinary copyright law examined in [Copyright & The Two Legal Layers](#brandolinis-copyright-and-layers). A primarily machine-generated copy without substantial human creative input is not merely unlicensed; it is a copyright violation that would exist under any license at all. + +**Ask**: Does the project say where its protocol knowledge came from? Does it credit the reference implementation, or claim “ground-up” status while its own history shows continuous ingestion of the reference’s source? Does its license carry the original copyright notice? The answers tell you, within minutes, which of two very different kinds of project you are dealing with. + +**Question 2: Who, or what, is the agent of the work?** + +This distinction, established in [Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution), is the trust foundation of everything else. Is there a human who decided what to build, judged what was correct, rejected what was wrong, understands what was shipped - and can answer for it, line by line and decision by decision, *without machine assistance*? Or is the machine the agent, with the human’s role reduced to the name, the account, and the signature? + +> This test has a sharper form: **would the project be meaningfully different if someone else had pressed the button?** If the answer is no - if any person could have been the signature and nothing would change - then the “author” is not the agent of the work. They are its facade, and the project is, in the most literal sense, worthless and unowned. + +A project with no owner is a project no one can answer for, and infrastructure with no one to answer for it has no place carrying other people’s traffic. + +### Other Signals To Look For + +Once the first two questions are answered, the following signals determine the verdict. None is alone decisive; together they form a pattern that is difficult to fake in the directions that matter. + +#### Provenance and attribution + +* **Credit to the reference.** Does the project name Reticulum’s reference implementation + in its README, its website, its licenses, and the code? Does it present itself as a port + or as a “ground-up” origin story? Absence of credit, in a field where every implementation + owes its existence to the reference, is not an oversight; it is a decision. + +* **License compliance.** For a derivative, the license conditions apply: the copyright + notice and permission notice in all copies and substantial portions, the harm condition, + the AI-training condition. A project whose license file claims a fresh copyright in the + operator’s name, over work that was generated from the reference, has failed the minimum + bar of honesty before any code is read. + +* **Disclosed provenance.** Is the use of machine assistance stated openly, or does the + project maintain machinery to conceal it - commit hooks that refuse attribution of + generation, contribution policies that declare machine output the human’s own, scrubbers + for personal traces, fictitious contributor identities? The first is the mark of a human + using a tool. The second is the mark of a record being manufactured. + +* **The author’s history.** Is there a prior record - projects, contributions, a body of + work that a person can look at and reasonably assess? A sudden, fully-formed “decade of experience” + appearing from nowhere, attached to a project of unprecedented scope, is a story that + contradicts itself. + +#### Agency and answerability + +* **Who answers the questions?** When technical questions are asked, does a human answer + with substance - going deeper, explaining trade-offs, admitting uncertainty - or do + answers deflect to process (“the CI verifies it”, “the proofs prove it”, “the audit + covered it”)? Are the answers themself machine generated? Deflection to process is + the substitute’s answer pattern: It names the machinery instead of the reasoning. + +* **Velocity commensurate with authorship.** Is the output volume compatible with human + authorship, review, and judgment? An implementation ten (or 42!) times the size of the reference, + produced in a fraction of the time by a single person, is not evidence of brilliance; it + is evidence of unchecked generation. Churn is part of the same signal: A project that + deletes half of everything it adds is not building; it is looping. + +* **Signs of development, growth and learning.** Do reversals exist? Contested decisions? + “We tried X and it was wrong, so we did Y”? Humans change their minds, admit mistakes, and + leave the wear of judgment in their history. Pure generation shows “the polish of its + absence”: uniform register, endless renaming, and errors discovered by the generator’s own + later runs, recorded as if they were planned milestones. + +* **Standing behind failures.** When something is wrong, does the human say “I chose this, + here is what I got wrong, here is the fix”? Or do corrections arrive as process language, + with nobody accepting that a decision was even made? A project whose history contains no + first-person acceptance of error contains no author. + +#### Engineering reality + +* **Honest benchmarks, or none.** If performance is claimed, is the baseline real - stock, + current, interpreted RNS, on the modern interface, at equal policy, with methodology + published in advance and reproducible by anyone? + +* **Interop with reality.** Is compatibility verified against the *current* reference + implementation - on real hardware, including the radio and serial interfaces this + protocol family lives on - in both directions, over long transfers, uptimes and edge cases? + +* **The readability standard.** Can a competent human read the core of this implementation + in a reasonable sitting, the way the 15,000-line reference can be read? Was human + readability a stated design goal, or an afterthought? A project that cannot be inspected + is a project asking for trust it has not earned and will never attend to. + +* **Nonstandard inventions.** Does the project “improve” on the protocol with its own + modes - new channel behaviour on shared spectrum, new rendezvous mechanisms, new crypto, + “post-quantum” replacements, “turbo” variants? Inventions that change behaviour on a + shared network are not features; they are forks of the airwaves, imposed on every other + node that shares the medium. A project that invents on top of a protocol it has not yet + correctly implemented is not advanced; it is dangerous to its neighbours. + +* **The public record.** The commit history is public. Read it. + +#### Network citizenship + +* **Honest presence.** Does the project identify itself honestly on the network, or does + it masquerade as something it is not? + +* **Coexistence.** Does it respect the shared medium and network conventions? A node that + is a bad neighbour on the spectrum is a hazard regardless of how well its code works in isolation. + +* **Community participation.** Does the author participate in the community as a member - + answering questions, contributing, learning - or only appear to advertise? The second is + not participation; it is exploiting the community as a broadcasting target. + +#### Monetary and influence signals + +* **Money under the claim.** Donations, funding, or commercial offers premised on claims + like “89× faster” or “formally proven” convert false marketing into a different category + of problem. When money changes hands on the strength of fabricated measurements, the + stakes are no longer theoretical. + +* **Tokens and “investment” vehicles.** Any implementation that surrounds itself with a + crypto token, a “coin”, or an investment pitch should be treated as what it is: A project + whose primary purpose is to earn the controller a profit, not open networking. + +* **Marketing-first ordering.** A polished website on day three, a twelve-language marketing + presence, a “benchmarks” page and a “get started” funnel existing before the protocol works + is a massive red flag. Real builders ship, then talk. The inverse order is the signature of + a project whose goal is attention. + +### The Conformal Surface + +One warning before the synthesis. When you evaluate any project, assume - as a working hypothesis - that its surface is an investment. The marketing, the design, the badge collection, the “proof records”, the fluent and confident prose: This is exactly where substitution invests, for the simple reason that it is where the audience looks first. Fluency is the *minimal conformal surface* of understanding, and the surface is not evidence of anything except that the author *wanted to look convincing*. If you find yourself impressed by the surface before you have asked Question 1 and Question 2, you are doing the evaluation in the order the substitute operator hoped you would. + +### Possible Verdicts + +The framework proposed here can yield three different verdicts: + +1. **Meets the standard.** A named human who can answer for the work and demonstrably does; + provenance disclosed; attribution given; honest benchmarks; interop + demonstrated against current, real RNS on real media; readable code; a maintenance + history that shows growth and learning. This standard is not high. It is what the + reference implementation has met, in public, for over a decade, and it is what any + project that wants other people’s traffic should be willing to meet in turn. +2. **Experimental, but honest.** A project that clearly labels itself as in-progress and + experimental (“do not use this yet”, in plain words, as the first thing a user sees) + discloses its provenance, credits the reference, and is being developed in the open by + humans who answer questions. Such projects should be encouraged. They are how the + ecosystem grows, new ideas are tested, and the framework above is designed to make an + honest experimental project *easy* to recognize, not hard. +3. **Does not meet the standard.** Unanswerable authorship, concealed provenance, fabricated + measurements, invented protocol behaviour, absent interop, marketing ahead of substance. + Such projects should be treated as unproven regardless of their surface, and as hazards + if they invite users onto shared networks. The community owes them exactly the + skepticism they have earned, and not a moment of engagement beyond that; the network’s + time is better spent elsewhere. + +### These Standards Are Reasonable + +I’ll close this guide by stating what these standards are *not*: They are neither a demand for perfection, nor a ban on machine assistance. Assistance is useful, when it is used to arrive at *higher levels of synthesis* than unaided work. It is not a requirement that an implementation be a clone of the reference; neither is it a requirement that it invents everything from scratch or aspires to be a [“clean-room”](#brandolinis-cleanroom-delusion) implementation. Good implementations of the protocol are very welcome, *however they come*, but working on one requires *serious* work, considerable skill, and **deep competence**. + +The reference implementation has met this standard for years, and its users know what that looks like. + +## The Movement Of A Dozen + +### Presentation, Elongated + +Whenever Reticulum defends itself, its license, or its community - or simply continues to exist - a familiar chorus appears. The register is always similar: *concern*. Concern about the direction of the project. Concern about its license. Concern about its governance. Concern about its “bullying” of “good-faith contributors”. Concern about the future of the ecosystem at the hands of a single maintainer. The chorus speaks in the plural, presents itself as a body of independent voices, and insists, with some frequency, that it is… *not alone*. + +The implicit claim under examination in this section is that there exists a *movement* of concerned individuals, spread across the ecosystem, all worried about Reticulum, and therefore (for some reason) deserving of a place at the table of decisions. + +A resolution of this claim requires one step: Count them. + +### Headcount + +This “movement” does have a headcount. It is not in the hundreds, and it is not in the dozens. It is a small number of people who appear, in various combinations and under various names, in the following roles: + +* Creators of the machine-generated “Reticulum implementations” examined in this chapter. +* Creators of articles praising those implementations and lamenting the state of the + reference, its moral shortcomings, its unavailability or lack of something it already has. +* Commenters “defending” the implementations when they are evaluated reasonably and critically, + most often by attempting simply to derail the discussion. +* Critics of the Reticulum License on “open source” grounds. +* “Concerned community members” objecting to the maintainer’s conduct. +* Campaigners on online platforms; and +* In some cases, a single individual performing *several* of these roles at once, under + different names, in the same week. + +The overlap is well documented at this point, across time and different platforms. The same phrasing, the same arguments, the same links, the same reactive reflexes, the same handful of accounts appearing in the same threads at the same moments. When the sockpuppets are unmasked (and they frequently unmask themselves) the cast does not grow, but rapidly shrinks. + +This is the most interesting single fact about the “movement”: **It isn’t one. It is a synthetic cast**, held together mostly by LLM-glue, reddit handles and hysteria. A cast is not a constituency. It performs; it does not represent. The difference matters quite a bit, because a great deal of this “movement’s” imagined power comes from the assumption that the *plural form* is actual evidence of plurality. If that sentence seemed opaque, notice how many times a statement or article uses “we” instead of “I”, and it will be less so. + +### Recycled Wine, Fermenting + +The cast is not only small, it is also, by any evidentiary standard, *forgetful*. Every major claim this “movement” advances has been advanced before, answered in public, with evidence, and often years ago - and is then advanced again, unchanged and completely ignoring any rationale or evidence presented previously (to the same people), as if the answer had never been written. + +* **The license argument.** Reticulum is “not really open source” because its license is not + approved by a particular orthodoxy. This is answered (now in a new and updated version, for the + fifth time) in full in [Open Source Means Open Source](#brandolinis-opensource). It was also + answered in public, at length, at the time of the license change - including the + arithmetic of who is actually restricted by which license. It is repeated *ad infinitum* anyway. + Quite a conversation starter, apparently. + +* **The distribution argument.** Reticulum is “not properly distributed” because it is not + packaged as a `.deb` or on some favoured catalogue. Reality: It is available on practically every + platform with a single command, packaged by the community in a wide range of channels, and + capable of updating itself over its own network. The argument has been answered; it is repeated. + +* **The “stepped back” narrative.** When the primary mirror of the project moved away from + a public internet platform, it was spun as the founder leaving for good, or now taking on dictatorial + powers, or abandoning his creation, or any variation or nonsensical combination thereof. + Those spins always center around justifying that *a vaccuum now needs to be filled*. + There was no such vaccuum. The narrative is repeated in various forms whenever convenient. + +* **The enclosure narrative.** The license is reframed as a “power grab” or an “enclosure” + of the commons - as if a license whose protocol is public domain and whose conditions + restrict only harm and appropriation were a form of enclosure. The [most recent](https://gaggl.com/blogs/2026-09-05-enclosure-by-good-intentions/) (and mostly incoherent) + expression of this narrative is, once again, fluent, polite, and factually hollow. The + bizarre arguments supporting the “article” include: Defunct and abandoned forks presented + as living, community forks bearing the very Reticulum License mislabeled as AGPL license vehicles + (created by “concerned users”), companion app forks correctly retaining the Creative Commons + licensing used as further evidence of the same and completely abandoned projects propped up + as being “the ecosystem”. Another case of LLM generated nonsense that the “author” didn’t bother checking. + The intent is clear here, simply produce more *mass* of the bullshit, so it can be further + referenced, regurgitated and linked to. + +* **The “bullying” narrative.** Whenever the community declines to treat manufactured + controversies as legitimate, or calmly documents the falsity of claims, or (Lord forbid) + moves a forum post for violating clearly stated forum rules, + the response is the same: The documentation is “bullying”, the community is “excluding” people, the + maintainer is “unprofessional”. In the most recent example, those accusations were made by someone who, in the + same week, publically called for the Reticulum maintainer’s “removal from the equation”, forged a moderator’s + username, attempted to drag unrelated individuals into the campaign, and presented a new + round of outright falsehoods. Contrary to popular belief, the accusation of incivility + is not the last resort of the wronged; it is the standard reflex of the exposed. + +None of the “arguments” engages the answers given repeatedly, and extensively. That is the point, and the strategy. The arguments are not produced for the purpose of being engaged; they are produced for the purpose of *being repeated* - the same wine, poured into new bottles, on a cycle. Each cycle is short, cheap to produce, and (thanks to freely available fluent text generation) now nearly effortless. The intended audience is not the community, which has heard it all before. The intended audience is the newcomer, who has not. + +### The Method of Madness + +The method behind the pattern is consistent and simple enough to be described precisely: + +**Bullshit asymmetry** + +Producing a fluent, plausibly-sourced smear is now the work of minutes. Refuting it to the standard this manual demands is the work of days, and the refuted smear is replaced by the next one within the week. This asymmetry isn’t just a fine point of the campaign; **it is the campaign**. The goal is exhaustion - the slow conversion of the community’s time and attention from building to defending. + +**Weaponized concern** + +The register of the campaign is almost always the register of solicitude: “we are worried about the ecosystem”, “we just want what is best for the community”, “this is about the future of the project”. The concern is directed, without exception, at the things the campaign wants changed, and the change it wants is always the same: **The replacement of the reference’s authority with its own**. Concern is the *costume*; capture is the choreography. It is the oldest form of cheap power grab in the book. + +**Event seizure** + +Any event - a license change, a platform move, a forum moderation decision, a subreddit closure, a security notice, even the most banal messages from maintainers or known contributors - are seized, stripped of their actual context, and re-narrated as evidence of the same pre-written story. The subreddit that was closed after its moderator vanished and ceased moderating (according to *prior agreement with said moderator*) becomes “the maintainer shutting down dissent”. Moving away from a highly centralized online platform becomes “the founder retreating”. The license becomes “the enclosure”. The pattern is so reliable that the story could be pre-written by a lightly mechanized quill; only the date changes. The actual real-world context of these events is documented, in public, in each case; the re-narration proceeds regardless. + +**The legitimacy circuit** + +The campaign invests heavily in the places where legitimacy is minted: Conference talks, blog platforms, social threads, and forums - presented as if these appearances constituted some sort of ecosystem-wide groundswell rather than the same dozen people moving through the same circuit. The LLM-generated articles cite the LLM-generated ports; the ports are praised in the articles; the managers of the ports spread the articles, and echo them on the forums and internet platforms; the conference presentations cite the forums. Random bypassers with the need for a cause watch the conference presentations and take on the holy duty of Internet Soldier. The circuit is closed, self-referential, and (to a reader encountering it fresh) convincing. It is also, entirely, **a loop of bullshit**. + +**The prior-work minefield** + +The machine-generated implementations have a consequence beyond attention: They flood the space with fake “prior work”. The effect, as the license discussion predicted in the beginning of 2025, is the creation of a minefield of sloppy repositories that can later be matched against any genuine project, and attempt to claim prior art, or even worse: Dissuade actual, honest developers or builders from taking up a real project they might have succeeded with, because they now believe it has already been done. Just as importantly, it also buries real efforts under machine-generated noise. The machine-ports are not failed attempts to contribute. They are (disregarding intentions, but effectively) the campaign’s long game, deployed as inventory. + +### A Persistent, But Fragile Triad + +This chapter as a whole has documented three fronts: The legal-ideological attack on the license ([Open Source Means Open Source](#brandolinis-opensource)), the substitution and usurpation pattern in machine-generated implementations ([Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution)), and the takeover narratives examined in this section. They are three fronts of the same operation, run by the same cast. + +* The license attack and other urgency-engineered narratives are the *cover*: They supply + the ideological justification for treating the reference as illegitimate, and needing replacement. +* The ports are the *inventory*: they supply the “replacements” that the narrative claims + the ecosystem needs. +* The takeover narrative is the *objective function*: the repeated, persistent, escalating claim that + the reference should be replaced, and that the speakers themself are the natural heirs. + +Each front depends on the others, and all three depend on a single, fragile assumption: That their audience cannot count. Restore the count, and the charade collapses into what it is: + +**A small group of people, obsessively orbiting a technology they did not build, synthetically producing the +appearance of a constituency they do not have, in service of a takeover they cannot justify.** + +### What The Pattern Is Not + +It is important, to also say what this pattern is *not*, exactly because the campaign depends on being mistaken for such things. + +**It is not criticism** + +The Reticulum community has always had lively, rigorous criticism - of decisions, of priorities, of direction - and it has always engaged that criticism on the merits, and changed course and development priorities many times. The license discussions at the time of the change were extensive, public, and answered in full, including with the critics themselves. Core protocol decisions were always discussed and evaluated in the community. The complex coordination and execution of several protocol upgrades between a loosely organised group of developers, node operators and users have succeeded surprisingly fluidly. All of these are success stories that the “critics” **always** ignore. Real criticism engages the content and accepts evidence. The campaign engages nothing. + +**It is not a community** + +Communities *build things*, maintain them, and have skin in the game; long-term users, operators of nodes, authors of real applications, people whose traffic flows through the network every day. A community has a stake. The “movement” only has an agenda. + +**It is not a debate** + +A debate has parties who evaluate arguments and evidence, and as a function of that, the debate moves forward, perpetually. The campaign’s arguments, as shown above, are not designed to survive contact with answers, but to be repeated past them. You cannot debate a loop. You can decline to perform for it, though. + +### Intent & Consequence + +While it would provide for interesting speculation, we do not need to know what the individuals in the cast *intend*, and this document will not speculate about their inner lives. People may believe their own narratives entirely, or partly, or not at all; **the pattern is the same in any case**, and the pattern is what matters here, since it is the exact thing that has been so insidiously destructive and resource wasting for the actual Reticulum project and community, ever since Reticulum was more widely discovered, popularized, and became a prime target for all sorts of grift known to man. + +The consequences are very real: + +* **Time**. The community’s scarcest resource is the attention of skilled people who actually build + and maintain the network. The campaign converts that attention into reactive defence, on a cycle + with no end. + +* **Harm**. Hastily machine-generated implementations, marketed as drop-in replacements and carrying + traffic onto shared networks, mislead users and can damage the network and its neighbours. + We, the actual reticulum community, all rely on these networks every day, and it is my belief + that we need to defend them. The fabricated measurements and laundered authorship examined in this chapter are not + editorial embellishments; they are the mechanism by which real users are induced to run + unverified, and often destructive software. + +* **Erosion of the currency of trust**. Every manufactured scandal, every fluently polite smear, every + fabricated “movement” debases the currency of trust and degrades it for **everyone**; + including, most of all, the honest projects that come after. This is deep harm, and + it is the primary reason this chapter exists. + +Whatever the intent - profit, control, attention, or a simple, obsessive inability to stop - the mechanism is the same, and the response should be *calibrated to the mechanism as a whole*, not to the individual person acting as the current avatar for it. + +### Recognition & Response + +For anyone who encounters the pattern fresh, here is a proposal on how to recognise it, and what to do about it. + +**Recognition:** The pattern is recognisable in minutes, once the signs are known: + +* Claims that have been answered before, repeated as if never answered. +* The register of solemn concern applied, without exception, in one direction. +* A severe allergic reaction to answering any questions posed. +* A cast that is small, overlapping, and frequently anonymous, with the *plural form* doing the + work of plurality. +* Sockpuppet theater: The same person or footsoldiers thereof appearing as several “supporters” + (and occasionally slipping up mid-performance). +* Articles, ports, and forum threads that cite and reference each other in a closed loop. +* The immediate, reflexive turn to “bullying”, “exclusion” and “toxicity” whenever a claim is refuted. +* A complete absence of engagement with the substance of the answers given, and a complete + absence of stake in the network itself. + +**Response:** A constructive response is one that is proportionate, and does not cost the +community its resources, sanity and dignity: + +* Engage the content once, on its merits (if any), with evidence, in public, and then refer to the + existing records. The answers already exist; they do not need to be re-derived for every new + bottle of piss-sour burgundy served from a man behind the curtains. I will do my best to keep this + chapter up to date with such answers and records, for easy reference, but other great resources + exist. +* Do not become part of the theater performance. The “movement” feeds on engagement in *any* form; + attention is its fuel, and outrage is as good as endorsement for them, if not better. +* Do the headcount. When the audience is reminded that a “movement” is a dozen people + recycling answered falsehoods, its projected power dissipates. The power was never real; + only the audience’s own assumption of scale can make the illusion effective. A polished-looking + “ground up” implementation might look like the work of many people, but is most likely + just the result of an LLM looping on a laptop for a couple of months (this is weird, but it is + the reality we now live in). Four different users suddenly singing in unison may look like the + representatives of a broader sentiment, but is most likely the same person hiding behind the same keyboard. +* Then, spend the saved time on the networks: On building real infrastructure, putting up nodes + and antennas, on real development, real maintenance, real coexistence, and on the people + *who actually use Reticulum*. The things that we can only do *together*, as humans. That is + what the fake “movement” cannot do, no matter how fluent and smooth its productions become. + +## Network Health & Coexistence + +### Substance Of The Networks + +Before examining health, we should consider what is being protected. The networks are not a repository. They are not a website, a social presence, or a set of marketing pages. They are a habitat: A living commons of communication, carried by, from a catious estimate, an intermesh now consisting of over a hundred thousand physical devices, embedded in a plethora of applications and packages, transporting terabytes of traffic every single day - real messages, real coordination, real people - across radios, serial lines, phones, laptops, and backbone servers, in cities, places and ways that no other network reaches. + +The protocol belongs to humanity; no one owns it. The network belongs to everyone on it, and its membership is defined by nothing other than participation: A node on a mast, a phone in a pocket, a server routing for its neighbourhood, a developer building on the commons. The network has no gatekeepers because it needs none; it is held together by the same physics and mathematics everywhere, and by a shared expectation of how members behave. That expectation - unwritten, unenforced by any central authority, and just as important as any code - is the subject of this section. The *Zen of Reticulum* calls the software a habitat. A habitat is healthy or unhealthy as a whole, and the health of this one is decided, every day, by the people who live in it. + +### Health Is A Property Of The Whole + +A network is not made healthy by the excellence of any single part. It is made healthy by the behaviour of every part on the shared medium, and how they interact. And the shared medium is the point. When your node transmits, it transmits into the same spectrum, the same line, the same time, the same mathematical address space, the same bandwidth that its neighbours depend on. + +The network cannot be certified by any single project’s claims. A node that is a bad neighbour, that invents its own channel behaviour on shared spectrum, that announces without discipline, that spawns tens of thousands of links to scrape the network, that floods and retries without mercy, is a hazard to every node that shares its medium, regardless of how well its “creator” imagines its own code to work in isolation. + +On a shared medium, “my software works” is not a complete sentence. The complete sentence is “my software works *and coexists*”. A network’s health deteriorates with its worst-behaved member, and every member has a responsibility to not be *that* member. There is no final, technical solution for this; the solutions are human. + +### A History Of What Works + +Let’s recall, because it is the ground truth this entire thing rests on, that the coexistence model has *worked* - is working, right now, **at scale**. Reticulum’s protocol decisions have been discussed and evaluated in the community, openly, for years. Protocol upgrades have been designed, coordinated, and executed between a loosely organised group of independent developers, node operators, and users - and have succeeded, repeatedly, without any corporate board, without any central command, and without the collapse that the skeptics predict every second week (while screaming for *GOVERNANCE*). The reference implementation has been developed in the open for over a decade, by a maintainer who answers for it, fixes bugs or issues within hours of their discovery, and is set down in code deliberately kept small enough (the entire protocol implementation under 15,000 lines, including its comments) for a human to read, verify, *and challenge*. + +This is the empirical baseline that every narrative examined in [A Movement Of A Dozen](#brandolinis-movement-of-a-dozen) conveniently ignores, in order to justify: + +* The claim that the project is a one-man dictatorship +* The claim that the community is excluded +* The claim that the networks need saving from their own founders + +The **reality**, documented and reproducible, is that a loose community of humans coordinates complex technical evolution *without* the apparatus the narratives insist is missing. The health of the networks is not a promise for the future; it is a demonstrated property of the past and present, under the leadership and community model that brought it into existence and navigated it through difficult decisions and situations over a decade. **My job is to keep it that way**, and you can be damned certain that I take it seriously. + +### The Role Of The Individual + +The networks are built by physical acts and human coordination. You cannot prompt an antenna into existence. No model can string up a dipole, or stand in the rain aligning a radio, or coordinate with a neighbour three valleys away about who covers which repeater frequency, or sit down with a newcomer and explain why their first node didn’t announce. These are the acts that make a network *organic* - present in the physical world, resilient because it is *real*, valuable because it is *human*. The machines and technology we use are tools aimed at a well-defined, openly described goal. But the networks themself are composed of intentional human actions, and every node operator is infrastructure for other humans. + +This has a corollary for the individual: You do not need permission, and you do not need to be an expert, to participate. Run a node. Help a neighbour. Ask questions in the community, and answer the questions you can. Build something small at first. The network grows by these acts, and they are the most meaningful ones - the things that can only be done together, as humans, in the physical world. The parasitic “movement” that haunts the peripheries of this ecosystem cannot do any of this. It cannot build a node because it does not exist, in any real connected and human sense; only people can, and people are precisely what a self-recurrent loop lacks. + +### The Place Of New Implementations + +The future of the network includes more implementations - and they are welcome. This chapter is not an argument against implementing Reticulum. The protocol is public domain, by design, and the network is made stronger by genuine diversity: More *good* implementations, honestly made, mean more resilience, more experimentation, more people who understand the protocol deeply *because they have built it themselves*. That is the goal: **For people to understand and own the technology they rely on**. Not to spew out 600,000 line rust ports that fills no meaningful gap or purpose. + +What the ecosystem needs, from every implementation, is the ordinary floor that [Evaluating A Reticulum Implementation](#brandolinis-evaluating) establishes, and that the reference has met for over a decade: A human who made it and answers for it; provenance disclosed; attribution given; benchmarks honest or absent; interop demonstrated against the real network; code a human can read. And it needs the one thing that costs nothing and changes everything: **Honest labeling**. + +An experimental implementation that says, plainly, as the first thing a user sees: “This is in-progress, experimental, do not depend on it yet, but help if you can”, that is a gift to the ecosystem. It contributes, it invites participation, and it protects users. + +The opposite, the polished “drop-in replacement”, does damage far beyond its own users: It dissuades the honest developers who might have built *the real thing*, because the polished slop persuades them the work is already done. That dissuasion is one of the quietest and most expensive harms in this entire affair, and the antidote is honesty at every project’s door. + +### Expanding The Commons + +Coexistence, reduced to its essentials, is a short formula; the duties of membership in a network no one owns: + +* **Be honest.** Say what you are, what you built, how you built it, and what you used to + build it. Label experimental work as experimental. Credit the work you build on, including + the reference implementation, in the licenses and in the prose. Concealment is not a + defence; it is a very clear diagnosis marker. + +* **Be owned.** Have a human who made the work and can answer for it. Use assistance, don’t + substitute. Never sign what you cannot answer for. The chain of accountability is the + community’s only verification at scale, and every link in it is a *person*, not a facade. + +* **Be a good neighbour.** Respect the shared mediums. Do not invent new behaviour in our + shared space and call it progress. The network belongs to its other members as much as + to you. + +* **Verify against the network.** Compatibility is a property demonstrated with actual nodes, + on actual media, against the actual current protocol, over a period of *years*, not 48 hours. + And not a claim pinned to an old snapshot over loopback. + +* **Participate as a member.** Ask, answer, help, build. *Advertising at* the community is not + the same as being part of it, and it is **not** the first thing you should do. + +None of this is a high bar. It is the bar the reference implementation has met, in public, for over a decade, and the bar the ecosystem has adopted organically itself, successfully, through every protocol upgrade it has ever coordinated, and everything running on Reticulum today, that people actually use. It is not a new requirement; it is the existing, working culture of the networks, now written down so that newcomers can find it and so that those who would exploit us cannot claim they never saw it. + +### Defence Of The Commons + +The networks need defending - not because they are under severe physical attacks (yet), but because attention, talent and resources is being stolen from them, trust is being mined against them, and its newcomers are being harvested by the machinery documented in this chapter. Defence, for a commons, has specific shapes, and it is not what the theater would like it to be. + +* Defence is **documentation**: Records kept public, of what was claimed, what was + answered, and what turned out true. +* Defence is **a headcount**: Calm, unexcited reminders that a “movement” might just be a dozen + people having a tantrum. +* Defence is **honesty in action**: The visible, ordinary practice of the good behaviour + by the people who actually run the networks. +* And defence is **building**: Every node raised, every page of *real* documentation, every + honest implementation, every new user helped into the community with the knowledge to know + what they are doing is more durable than any rebuttal, because it adds to the thing being + defended. + +--- + +**The theatre cannot keep up with a network.** + +**It can only orbit it, while it recycles its own sour piss.** + +--- + +A lot of us rely on these networks every day. They carry our messages, our coordination, our friendships, and in some places, our safety. That is exactly why they are a target: + +They are valuable, free, and very hard to shut down. The response is not to become aggressive. It is to be *more* of what the network already is: Real, open, owned, and shared. + +*Mark* + +## Addendum A: The Prns Case + +### Purpose & Scope + +This section provides a concrete example, which future evaluations can use as a template. Its purpose is not to be the last word on this particular subject, but to be an example of how the ideas in this chapter can be applied, and to make the next such examination easier. + +The subject of this case study is **Prns**, a project published at the repository `github.com/KenAKAFrosty/Prns`, presented as a “ground-up implementation of Reticulum, written in Rust”, marketed as faster, safer, and more strictly tested than the reference, widely promoted with the claim of “up to 89× the throughput” of the reference implementation, and an “author” actively engaged in the tactics described in [A Movement Of A Dozen](#brandolinis-recycled-wine) on online platforms. The record described below is the project’s own, and sourced from its GitHub repository, analyzed locally. + +### The Project In Brief + +* **Time span.** 3,374 commits between 2026-05-26 and 2026-09-12: approximately 110 days, + at a mean rate of ~31 commits per day. Monthly: 132 / 1,137 / 1,097 / 805 / 203. + +* **Authorship.** 3,252 of 3,374 commits (96.4%) are authored by a single account. A + second identity, “Prns Tests [tests@example.test](mailto:tests@example.test)” - a fictitious identity on a reserved + domain - contributed 35 commits, every one of them website and marketing content. + +* **Size.** 3,519 tracked files; 1,983 Rust files; 636,226 lines of Rust; approximately + 22.7 MB of Rust source; 69.5 MB of total repository content. + +* **Scope claimed.** A daemon (“drop-in replacement” for the reference daemon), embedded + firmware for three microcontroller families (including six ESP32-S3 board variants and + nRF52840), SDKs and bindings for nine languages, a browser-based node and web flasher, a + twelve-language website, a benchmark apparatus with its own publication and “proof” + pipeline, and a validation hub with oracles, fuzzing, mutation testing, and formal-proof + claims. + +* **Marketing claims.** “Ground-up implementation of Reticulum”; “up to 89× the + throughput”; “48× smaller peak-memory footprint”; “33× the energy efficiency”; + “Measured, not just claimed”; “Enforced, then audited”; “byte-for-byte wire parity with + the reference implementation”; “works with Sideband, NomadNet, MeshChat, etc.”; + “no_std (no alloc required either)”. + +* **Status at the time of writing.** Version 0.3.7; published version history begins at + 0.3.0. The repository continues to receive commits. + +### Question 1: Is this a clean implementation, or was it directly generated from the reference? + +The first of the two deciding questions from [Evaluating A Reticulum Implementation](#brandolinis-evaluating) is settled by the project’s own record. An actual [clean-room](#brandolinis-cleanroom-delusion) implementation, reasoned out and written by humans, would owe nothing to any license. The data available shows clearly that Prns is not that. + +* **The founding state.** The first commit, “Scaffold Personal Reticulum suite”, contains + the scaffolding of not one but two ports - `personal-rns` and `personal-lxmf`, the latter + being the reference’s companion messaging protocol - together with a daemon scaffold and + a 233-line founding document, `docs/build-ethos.md`. That document declares the project’s + goal as a “performance-focused drop-in-replacement for rnsd” and its governing principle + as: “Port the contract, not the implementation.” It further states directly to the + machine-loop, that **“You owe the reference fidelity at exactly two boundaries: + The wire… The behavior. … Between those two boundaries, the model is yours”**. + At this point, the very first commit, effectively the whole of the implementation design + and any relevant decisions are handed over to the LLM. + +* **Continuous ingestion from the reference.** 506 commits reference RNS or Reticulum + source behaviour; the word “parity” appears in 49 commit messages. Commits cite the reference + implementation’s own source locations (for example `Transport.py:1367`) when correcting + their own divergences and mistakes. + +* **Byte-level fidelity as an explicit goal.** Within 48 hours of the first commit, the + record shows a “crypto adapter - vetted primitives, byte-exact vs RNS 1.3.1”, and a wire + implementation matching the reference’s packet header layout. The project’s own + validation apparatus decodes wire vectors using the reference implementation’s own + packet parser, and the interop suite consists of real, stock-RNS peer nodes - that is, + the reference source itself, used as the ground truth against which this LLM output is + checked, and committed as accepted and verified after 48 hours of the project’s recorded start. + +* **The marketing mismatch.** The same record that documents all of the above describes the + project, publicly, as “a ground-up implementation of Reticulum” - while declining, on its + website, to link to the reference implementation at all: the entire tree mentions the + reference’s author in six files, and the website in none. + +Conclusion: the project’s own history and commit record establishes that it was generated directly from the reference implementation’s source code, not reasoned out from the public-domain protocol. It is a derivative of licensed work within the meaning of [the Reticulum License](#brandolinis-what-the-license-is) and [general copyright law](#brandolinis-copyright-and-layers). The “ground-up” claim, which carries its entire legal and marketing posture, is disproven by the project’s own history. + +### Question 2: Who, or what, is the agent of the work? + +The second deciding question is answered by the application of [Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution) criteria to the project. + +**Scope that no human could have authored** + +636,226 lines of Rust in 110 days is approximately 5,800 lines per day, every day, including weekends - with 149 commits recorded between midnight and 06:00, and Saturday the single busiest weekday. No human review or decision capacity is commensurable with this volume; the review capacity and the output volume are structurally incommensurable, which is the definition of unauthored scope. + +**Uniform generation** + +The record shows no sign of human development, growth, or learning: No contested decisions, no style drift. Instead: endless renaming (in the first 48 hours: `State → EngineState → TickInput → TickOutput`), uniform fluent register in every commit, and the exact same, synthetic voice in code, documentation, and website copy. + +**Discovery by regeneration** + +Corrections arrived by the machine’s own subsequent runs, recorded as planned milestones. In early July 2026, a series of “core review” commits documented, in the project’s own words: + +* announce-ID history “was unbounded per-slot growth” (`54cc8d601`); +* interface announce limiting could “leak a sustained flood” (`9d27af75c`); +* a “phantom-airtime leak” where frames “used to vanish silently” (`4ed75ffdd`); +* Group-packet deduplication “which RNS does not do” - a behaviour the reference never had, + implemented and later removed (`edd8e72be`); +* “both `unwrap_or(&[])` arms were unreachable dead defaults” (`74bea355e`); +* a benchmark crate “hasn’t compiled since” a prior rename, undetected for weeks because it + was outside the CI’s workspace (`86240b027`). + +Earlier still: the record shows a “>1 MiB RNS-to-Prns interop stall” closed three weeks in +(`cc4d524a3`), and a known send-path hang shipped with the note “typed fast-fail a +candidate for later” (`a010e6613`). + +**Laundered provenance** + +The repository contains a committed commit-message hook (`.githooks/commit-msg`) that *blocks* any commit containing attribution for machine generation (“generated with claude/codex/copilot/cursor/gemini”, “co-authored-by”), with the explanation “The committer owns the commit”. The contributing guide is explicit: “AI tools … are welcome … what you submit is *yours*”, and describes the contributing population as “both human and automated contributors”. The fictitious “Prns Tests” identity completes the picture: A manufactured, unknowable contributor, used for marketing content. + +**Authorship by assignment** + +The human whose name is on the work cannot answer for it, because the choices were never made by a human, and only the general shape and constraints of the outward presentation was. Nothing in the project’s history shows an individual explaining a design decision, accepting a mistake in the first person, or going deeper under technical questioning; the record shows process language and marketing instead. Per the earlier mentioned test: any other person could have pressed the same button, and nothing would be different. The project is effectively unowned, and void of value. + +By the criteria of [Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution), this is substitution. The machine was the agent of the work; the “author” was a facade. + +### The performance claims + +The project’s central marketing claim - “up to 89× the throughput” of the reference - is also its most completely documented failure, because the project published the evidence of its own measurement. The apparatus, the results, and the problems are all on the record. + +**The claim** + +The README states “up to 89× the throughput”; the on-network marketing page repeats “up to 89× the throughput, 48× smaller peak-memory footprint, and 33× the energy efficiency of stock RNS 1.4.2”; the website’s front page carries the tagline “Measured, not just claimed”. + +**The apparatus** + +The reference is loaded through `benchmarks/reference/compiled_reference.py`, which installs `pyximport` and then asserts two things: that `RNS.compiled == True`, and that at least *one* RNS module was loaded from a native extension. The project’s own published “proof” records show exactly what those checks captured, on every platform: + +```default +aarch64-apple-darwin: .../RNS.cpython-313-darwin.so, Cython 3.2.8, Python 3.13.13 +x86_64-unknown-linux-gnu: .../RNS.cpython-313-x86_64-linux-gnu.so, gcc 11.4.0 +x86_64-pc-windows-msvc: ~/.prns-oc/lib.win-amd64-cpython-313/RNS.cp313-win_amd64.pyd +``` + +In every case the recorded native module is the **top-level package only** - `RNS.so`, nothing below it. Nothing named `RNS.Transport`, `RNS.Destination`, `RNS.Packet`, `RNS.Link`, or `RNS.Resource` ever appears, because *nothing below the top level was ever compiled*. Nobody bothered to check or verify *anything* here. + +The machine output was simply taken for truth, and a full marketing strategy was spun and produced on it. “RNS 1.4.2 (compiled)” - the label used in every table, chart, and marketing page - *is not a mode of RNS that exists*, but the hallucinations of a machine, which the humans created a marketing strategy on. In reality, it is the old `CRNS` development shim, whose top-level-only, debug-oriented “compilation” is slower than plain interpreted RNS, and which was *defunct for over a year* before these benchmarks were published. + +**Interface choices** + +The harness writes the reference’s configuration itself (`benchmarks/reference/participant_node.py`): `TCPClientInterface` for the initiator, `TCPServerInterface` for the responder and both relay sides, with `UDPInterface` as the abstract wire. The reference was never given its modern `BackboneInterface` on any platform, forcing the slowest possible interrfaces. The interface selection is never mentioned in any methodology text. + +**The policy** + +The published default-policy tables record the asymmetry directly: Prns at 500 Mbps / 128 KiB TCP policy against the reference at 10 Mbps / 8 KiB - slyly footnoted as “preserves each implementation’s normal TCP policy” (in the case of RNS, a conservative default policy that was selected to prioritize coexistence on slower, shared links, requiring the user to dial it up to full speed if they knew what they were doing). Raw transport “throughput” ratios of 20.65× (Linux) and 38.84× (Windows) are therefore mostly policy, not engine. + +**The cross-host evidence** + +The published results show the same scenario producing wildly different ratios by host, and the variance is entirely in the reference artifact: + +| Host | Prns, single-packet | “Reference”, single-packet | Ratio | +|-------------------------|-----------------------|------------------------------|---------| +| macOS (Apple M4) | 37.4k/s | 420/s | 89.09× | +| Linux (i7-1260P) | 25.3k/s | 3.5k/s | 7.19× | +| Windows (Ryzen 5 5600X) | 30.8k/s | 3.9k/s | 8.00× | + +Prns is consistent (25–37k/s). The reference artifact collapses to different depths on different hosts, and the single worst collapse - 420 packets per second on macOS - is the cell selected as the global headline. The “89×” is not a measure of Prns; it is a measure of how badly the broken baseline happened to fail on one host. + +For reality calibration: Stock, interpreted RNS 1.5.4 on an ordinary mid-range laptop, single core, sustains roughly 30,000 single-packet deliveries per second (including ephemeral-key decryption), ~175,000–280,000 packets per second in transit relay, and on the order of 10 Gbps at 16 KiB payloads. The project’s “compiled” artifact measured 420–3,900 packets per second for its single-packet scenario: An order of magnitude or more *below* stock interpreted RNS. The comparison being marketed was not “Rust vs Python”; **it was “an implementation running under optimal conditions versus a mislabeled, broken shim on a slow legacy interface at a severe policy disadvantage”**. + +**The equalized rows** + +The project’s own “1 Gbps policy” rows, in which both sides are explicitly configured identically, publish ratios of roughly 2.4–8.4× across all hosts and scenarios - still against the broken baseline, but nowhere near 89×, and consistent with the ordinary, uncontroversial observation that a native implementation tends to outperform an interpreted one in raw throughput. That point needed no fudging to make, and is banal. + +Interestingly, though, it seems that Prns is really only *marginally* faster than a Python implementation, running in interpreted mode, on a single CPU core. + +**Assessment** + +The front page says “Measured, not just claimed.” The record shows the opposite ordering: claimed, and arranged to look measured. No methodology section anywhere states what “compiled” means, that it is a deprecated development shim, that it builds debug targets, or which interface the reference was given; the one statement of the policy asymmetry appears in a footnote of the results tables themselves. If they did not need to fudge it, they would have published the method clearly. + +### Overall Evaluation + +Evaluated against the conditions of [Evaluating A Reticulum Implementation](#brandolinis-evaluating): + +* **Provenance and attribution.** Fails: The fake “ground-up” origin story; zero reference links + on the website; a single well-hidden link in the README; a license file reading + `Copyright (c) 2026 The Prns Authors` over work directly generated from the licensed reference; + no original copyright or permission notice anywhere. + +* **Agency and answerability.** Fails on every criterion of [Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution): + Unauthored scope, uniform generation, discovery by regeneration, laundered provenance, + authorship by assignment. + +* **Engineering.** Fails: The benchmark apparatus above; interop demonstrated only + against a pinned, outdated reference version over loopback while the marketing claims current + parity, interop failures with stock RNS; vendored prebuilt binaries and a republished fork + of an upstream crate (`nrf-softdevice 0.1.0-prns.1`) with no verifiable provenance; + committed WASM bundles. + +* **Network behaviour.** Fails: Invented spectrum behaviour and compatibility claims + about third-party applications of the reference ecosystem (Sideband, NomadNet, MeshChat) + that are not established by any evidence. + +* **Monetary and influence signals.** The marketing apparatus - website before protocol, + day-three twelve-language marketing, false benchmark headlines, “audited” and “formal proof” + claims - the conformal surface described in [Evaluating A Reticulum Implementation](#brandolinis-evaluating): + is where this project invested. + +### Licensing Analysis + +Applying the two legal layers established in [Copyright & The Two Legal Layers](#brandolinis-copyright-and-layers): + +**Layer A - copyright infringement (license-independent)** + +The record shows a direct copy roundtrip: the licensed reference implementation fed into a machine, transformed, at a scale and cadence no human could review, with a license file asserting a fresh copyright in the operator’s name and no acknowledgment of the work the project was generated from. No substantial, new human creative input is demonstrated anywhere in the record - the founding document explicitly frames the design as an instructed port of the reference’s contract. A primarily machine-generated copy of a copyrighted work, not accompanied by demonstrable substantial human creative input, is a derivative work over which the copier holds no copyright, and a reproduction of which without the original author’s permission infringes the original author’s copyright. This holds under any license, MIT included. The operator’s copyright claim over the result is, on this evidence, not merely unsubstantiated; it is the absence of one, directly asserted in the project’s own writing. + +**Layer B - license conditions (Reticulum License specific)** + +Modern Reticulum - the current wire format, the AES-256-based link encryption, ratchets, the cryptographic machinery as it exists today - has been published under the Reticulum License since April 15, 2025, effective from release 0.9.4 and every release since. As a derivative of that work, the license’s conditions attach: The copyright and permission notice must be included in all copies and substantial portions; the AI-training condition must be honoured; the harm condition must be honoured. The record shows none of the notice requirements met, and a production process that consists of the licensed work being ingested into a machine and regurgitated, at industrial scale and cadence. + +**The cascading consequence** + +Prns is distributed claiming dual MIT/Apache-2.0 licensing. It is, however, a direct derivative of Reticulum-licensed work, and the claimed grant is therefore void. Every downstream project that builds on Prns believing it is MIT/Apache-licensed is building on a grant that does not exist. The users of Prns, and all software developers using it, have in effect, been placed under conditions they were never told about. The “ground-up” claim is not merely false; it is the sole load-bearing element of an entire licensing posture, and it fails spectacularly. + +### Consequences + +The consequences of this pattern are examined in the following sections: The harm to users and to the network in [A Movement Of A Dozen](#brandolinis-movement-of-a-dozen), and the human dimension in [Network Health & Coexistence](#brandolinis-health-and-coexistence). The contribution of this addendum is narrower and intended as an instructive example: This is what a substitution project looks like, in full, on its own record. It is a reference example for [Evaluating A Reticulum Implementation](#brandolinis-evaluating), and it demonstrates, in one case, most of the elements this chapter describes. + +### Verdict + +Applying the three verdicts of [Evaluating A Reticulum Implementation](#brandolinis-evaluating), this project does not meet the standard. It is not “experimental but honest” - it is not labeled as experimental anywhere; the first thing users saw was a polished marketing presence promising a finished, tested, drop-in replacement. It is a project whose central claims are fabricated (the performance apparatus), whose provenance is laundered (the authorship machinery), whose foundation is misrepresented (the “ground-up” story), whose core semantics were learned late and by regeneration, and whose operator cannot possibly answer for any of it. It is also a blatant copyright violation of the reference implementation. + +The proposed conclusion, for users and for the network: Treat the Prns project as hostile regardless of its polished surface, and as a hazard insofar as it invites users onto shared networks. Nothing in this section is a judgment about the people involved; it is a reading of the results produced, their history and how they came to be, which in the regrettable lack of any human authorship is the only thing that can be expected to be held to account. + +### Dating + +This examination reflects the publicly available material as of September 2026; the repository in question continued to receive commits at the time of writing, so readers should treat citations to commits and files as point-in-time evidence. A [forensics snapshot](https://github.com/markqvist/forensics_prns) is publicly available on GitHub. \ No newline at end of file diff --git a/Changelog.md b/Changelog.md index 9ee5d91b..b0e0841c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,89 @@ +### 2026-09-29: RNS 1.5.5 + +This release adds live interface attach, detach and reload, as well as significant improvements to interface discovery. Auto-connecting interfaces is now also supported on Windows and macOS. + +It also brings improvements to `rngit` and fixes discovered `I2PInterface` configuration snippets, along with a number of other bugs. + +**Changes** +- Added ability to `--attach`, `--detach` and `--reload` interfaces to the `rnstatus` utility +- Added interface discovery auto-connect support on Windows and macOS +- Added ability to download micron-converted versions of markdown files to the `rngit` page node +- Added workdoc counts to filter scope links to the `rngit` page node +- Added version info to `rnstatus` discovered interfaces output +- Added `--show-stale` and `--show-unknown` options to `rnstatus` +- Added sequential naming of auto-connected interfaces on announced name collisions +- Added auto-connect implementation and version criteria filtering +- Added configuration option for allowing auto-connects to discovered interfaces with missing version info +- Improved sanitization of nonsensical interface discovery IFAC announce data +- Fixed `I2PInterface` discovery config snippets not including `.b32.i2p` +- Fixed timeout and response rejects not being processed for single-packet requests, by **JRG** +- Fixed missing configurable property propagations on spawned interfaces, by **JRG** +- Fixed ingress control producer comprehension at mid-watermark using incorrect variable name for interface type check, by **JRG** +- Fixed instances of `announce_cap` property ensurance logic not storing announce cap value as a fraction, by **JRG** +- Fixed a potential race condition in `LocalInterface` initialization. +- Updated documentation and manual + +**Verified Retrieval** +You can retrieve and verify this release over Reticulum using the built-in `rngit release` utility. To retrieve only the installation `.whl` package, and the release manifest for future updates, you can use: + +```sh +rngit release rns://7649a50d84610232d1416b41d2896aff/reticulum/reticulum fetch "latest:rns-*.whl" --signer bc7291552be7a58f361522990465165c +``` + +To download all artifacts, including the documentation and source archive, you can use the following command: + +```sh +rngit release rns://7649a50d84610232d1416b41d2896aff/reticulum/reticulum fetch latest:all --signer bc7291552be7a58f361522990465165c +``` + +**Release Signatures** +Release artifacts include a signed `rsm` release manifest and `rsg` signature files that can be validated against the RNS release signing identity `` using `rngit` or `rnid`. To perform an offline verification of all release artifacts using a manifest: + +```sh +rngit release rns_*.rsm verify --signer bc7291552be7a58f361522990465165c +``` + +To verify release artifacts using individual `rsg` files, while also verifying the manifest itself, download the `rsm` and `rsg` signatures, make sure they are in the same folder as the release artifact, and run `rnid` signature verification with the release identity as the required signer: + +```sh +rnid -i bc7291552be7a58f361522990465165c -V rns_*.rsm *.rsg +``` + +The `rnid` utility will then verify the signatures, and display whether they are valid. If the signature cannot be verified, the release has been tampered with and should be discarded. + +### 2026-09-11: RNS 1.5.4 + +This release improves RNode BLE connectivity reliability on desktop operating systems. + +**Changes** +- Fixed RNode BLE device address acquisition on windows, by **Nickie Deuxyeux** +- Fixed RNode BLE re-connection deadlock on desktop +- Improved RNode BLE reconnect reliability + +### 2026-09-10: RNS 1.5.3 + +This maintenance release adds functionality to, and fixes bugs in `rngit`, and includes a few other optimizations and improvements. + +**Changes** +- Added media request handler to `rngit`, for serving images to `nomadnet` clients +- Added media conversion handler to `rngit`, auto-converting images to webp +- Added importable helper method for using the `rngit` media converter in other programs +- Added a `no_ident` template to the `rngit` page node +- Added immediate activation of changed permissions with `rngit perms` +- Added optimized HDLC framer +- Fixed `rngit` repo admins not being able activate/complete workdocs from other users, by **Bergie** +- Fixed a typo, I'm positively certain this is the last one + +### 2026-08-28: RNS 1.5.2 + +This maintenance release fixes a regression in resource transfers that was introduced in 1.5.1, an `I2PInterface` bug, and sets dataplane control parameters to default values that are actually sensible. If you installed `1.5.1`, it's update time again, baby. + +**Changes** +- Tuned dataplane control parameters +- Added example for blocking unidentified page node peers to `rngit` default config +- Fixed regression in resource transfers causing some `rngit` file downloads to fail +- Fixed keepalive frames being passed to transport core on `I2PInterface` + ### 2026-08-28: RNS 1.5.1 This release focuses on dataplane control, memory bounding and transport throughput, with adaptive ingress and egress control for interfaces, a new (and very efficient) zero-copy coalescing transmit buffer, an optimized HDLC deframer, and a range of other improvements to the inbound packet processing paths. It also introduces support for live profiling, and various new diagnostics output in `rnstatus`, along with a number of bug fixes and general improvements. @@ -44,34 +130,6 @@ This release focuses on dataplane control, memory bounding and transport through - Fixed a latent bug in the AES module, where an exception would not resolve it's exception description correctly, and instead raise another exception. - Removed dead Python 2 code from `umsgpack` -**Verified Retrieval** -You can retrieve and verify this release over Reticulum using the built-in `rngit release` utility. To retrieve only the installation `.whl` package, and the release manifest for future updates, you can use: - -```sh -rngit release rns://7649a50d84610232d1416b41d2896aff/reticulum/reticulum fetch "latest:rns-*.whl" --signer bc7291552be7a58f361522990465165c -``` - -To download all artifacts, including the documentation and source archive, you can use the following command: - -```sh -rngit release rns://7649a50d84610232d1416b41d2896aff/reticulum/reticulum fetch latest:all --signer bc7291552be7a58f361522990465165c -``` - -**Release Signatures** -Release artifacts include a signed `rsm` release manifest and `rsg` signature files that can be validated against the RNS release signing identity `` using `rngit` or `rnid`. To perform an offline verification of all release artifacts using a manifest: - -```sh -rngit release rns_*.rsm verify --signer bc7291552be7a58f361522990465165c -``` - -To verify release artifacts using individual `rsg` files, while also verifying the manifest itself, download the `rsm` and `rsg` signatures, make sure they are in the same folder as the release artifact, and run `rnid` signature verification with the release identity as the required signer: - -```sh -rnid -i bc7291552be7a58f361522990465165c -V rns_*.rsm *.rsg -``` - -The `rnid` utility will then verify the signatures, and display whether they are valid. If the signature cannot be verified, the release has been tampered with and should be discarded. - ### 2026-08-22: RNS 1.5.0 This release significantly improves the core Transport handling of RNS, with a priority-based ingress queue backend, substantially improved efficiency of both data and management traffic handling, more efficient ingress/egress limiting, and a long list of other improvements and bugfixes. diff --git a/Contributing.md b/Contributing.md index 3965f844..38372f79 100644 --- a/Contributing.md +++ b/Contributing.md @@ -2,57 +2,66 @@ Welcome, and thank you for your interest in contributing to Reticulum! -Apart from writing code, there are many ways in which you can contribute. Before interacting with this community, read these short and simple guidelines. +Before interacting with this community, read these short and simple guidelines. + +If you didn't shit your pants after reading this document, you may well find that we are all really quite cuddly and nice to be around. Mostly. ## Expected Conduct -First and foremost, there is one simple requirement for taking part in this community: While we primarily interact virtually, your actions matter and have real consequences. Therefore: **Act like a responsible, civilized person** - especially in the face of disputes and heated disagreements. Speak your mind here; discussions are welcome. Just do so in the spirit of being face-to-face with everyone else. Thank you. +First and foremost, there is one simple requirement for taking part in the development of this technology: While we primarily interact virtually, your actions matter and have real consequences. Therefore: **Act like a responsible, civilized person** - especially in the face of disputes and heated disagreements. Speak your mind here; discussions are welcome. Just do so in the spirit of being face-to-face with everyone else. Thank you. -In order to keep the discussion forums and issue trackers navigable and useful, the following types of posts will be deleted without notice: +In order to keep the discourse navigable and useful, the following types of posts and inquiries will be deleted and ignored: - Spam. -- Questions that have already been adequately answered elsewhere. Use the search function. -- Low-effort posts or comments that contain no actual information or useful content. This is not a tea-house. +- Questions that have already been adequately answered elsewhere. Utilize search functions. +- Low-effort posts or comments that contain no actual information or useful substance. [This is not a tea-house](./This%20Is%20Not%20a%20Teahouse.md). - Post or comments solely containing personal opinions or beliefs without adding anything to the discussion. Facebook and X exists. - Content that simply waste the developer's / maintainer's time with completely obvious "ideas", "insights" or "recommendations". Yes, we have *at least* 8 neurons ourselves. - Posts that fail to understand that developing a highly complex software project with a very small amount of resources and people takes time. Imagining perfection on our behalf is useless. -If you're new to the community and start out your engagement with any of the above transgressions, you will simply be banned without notice or explanation, and your post will be deleted. +If you're new to the community and start out your engagement with any of the above transgressions, you will simply be banned permanently without notice or explanation, and any further communication from you will be ignored. + +Except for the case of real, well-grounded, clearly documented, human-written security advisories, technical investigations or bug reports, if your inquiry or communication is not attached to a Reticulum Identity, expect it to be ignored. If you find this "harsh", "unfair" or "unwelcoming", go somewhere else. This is not social club, but a work environment for the people contributing to the project. -## Asking Questions +## Reporting Bugs -If you want to ask a question, **do not open an issue**. The issue tracker is used by people *working on Reticulum* to track bugs, issues and improvements. Instead, ask away on the [discussions](https://github.com/markqvist/Reticulum/discussions). - -Do not post feature requests or general ideas on the issue tracker, or in direct messages to the primary developers. You are much more likely to get a response and start a constructive discussion by posting your ideas in the public channels created for these purposes. - -## Reporting Issues - -If you have found a bug or issue in this project, please report it using the [issue tracker](https://github.com/markqvist/Reticulum/issues). Be sure to include details on how to reproduce the bug. - -Anything submitted to the issue tracker that does not follow these guidelines will be closed and removed without comments or explanation. +If you have found a bug or issue in this project, please report it to the maintainer over LXMF, or if strictly not possible, over email. Detailed and serious bug reports can also be posted in the various on-network forums and RRC channels that the developers frequent. Due to the realities described in [This Is Not a Teahouse](./This%20Is%20Not%20a%20Teahouse.md), there is no way to report issues or request features over the internet. ## Writing Code -If you are interested in contributing code, fixing open issues or adding features, please coordinate the effort with the maintainer or one of the main developers **before** submitting a pull request. Before deciding to contribute, it is also a good idea to ensure your efforts are in alignment with the [Roadmap](./Roadmap.md) and current development focus. +Patches and code contributions are *generally* only welcomed from developers already known to the community, with a proven track-record of competence, skill, careful and considerate design and responsible conduct. If we do not know you yet, but you have created something that you believe lives up to such standards, we are eager to hear from you. -Pull requests have a high chance of being accepted if they are: +Current development priorities and work documents are not publicly available on the internet, but shared and coordinated directly between the developers over Reticulum itself, following the principles outlined in [Distributed Development](https://reticulum.network/manual/distributed.html). -- In alignment with the [Roadmap](./Roadmap.md) or solve an open issue or feature request -- Sufficiently tested to work with all API functions, and pass the standard test suite -- Functionally and conceptually complete and well-designed -- Not simply formatting or code style changes -- Well-documented +## Commit Signing -Even new ideas and proposals that have not been approved by a maintainer, or fall outside the established roadmap, are *occasionally* accepted - if they possess the remaining of the above qualities. If not, they will be closed and removed without comments or explanation. +All commits in Reticulum and related projects **must** be signed with a Reticulum identity. If you want your author credentials to be included directly in the commit log, ensure that you have [configured commit signing](https://reticulum.network/manual/git.html#commit-signing). Bare patches submitted manually or fetched remote commits without signatures are still very welcome, but we will review, squash merge and sign with the key of the maintainer that approved the changes. Attribution will be provided in the commit message instead (unless you wish to remain anonymous). -## Generative AI Policy +## Machine Assistance & LLMs -Contributions written using large language models (LLMs) or other generative 'AI' programs are prohibited. LLMs produce errors so frequently and in a way that is so unlike human error that such issues are incredibly time-consuming to spot and fix. This is not a worthwhile tradeoff for Reticulum. +For a highly complex, critical piece of cryptographically based networking infrastructure, we should not need to state the following, but alas, experience has proven otherwise. Therefore: -This applies to all Reticulum-related projects and documentation, as well as all submitted issues and discussion in official channels, except in cases where language translation and/or speech recogntion technologies are required for communication. +**Including material generated using LLMs or other "AI" programs in Reticulum is, almost without exception, prohibited.** + +Before even *thinking* about using a generative software system to "create" something for Reticulum, read [Brandolini's Reference](https://reticulum.network/manual/brandolinis.html), in full. If you do not have the capacity for that, you have failed the first requirement for contributing: Basic literacy. + +*If* you are not already a known contributor with a proven record of being able to responsibly handle these tools, a **full** audit trail of all ML-utilizing workflows, including prompts, LLM reasoning traces, tool calls and outputs (that is, the *entire*, unaltered session log) will need to be provided with any proposed contribution. Without that, we will not even *consider* looking at it. + +This applies to all Reticulum-related projects and documentation, as well as all submitted issues, reports and discussion, **except** of course in cases where language translation, speech recogntion, or other assistive technologies are required. + +In **all** circumstances, clear disclosure is **mandatory**. Any piece of material, file, code snippet, method, function or similar that was generated with machine assistance must be prepended with a disclosure header or comment that states the framework, exact model used and reviewer, such as: + +```python +# Generated with lc/deepseek_v4_flash_q8_k_xl +# Reviewed and corrected by Mark Qvist +``` + +Additionally, any explanatory comments or doc-strings generated by software must be manually re-written in clear, concise language by the reviewer stated in the disclosure header. ## Contributor License Agreement By contributing code to this project, you agree that copyright for the code is transferred to the Reticulum maintainers and that the code is irrevocably placed under the [Reticulum License](./LICENSE). + +For a more in-depth elaboration on the current CLA position, see [this post](https://rns.recipes/forum/general/brandolinis-reference-or-alternatively-agentsmd?page=1#post-3002). diff --git a/README.md b/README.md index 2e2f8b2e..f04c6b0e 100755 --- a/README.md +++ b/README.md @@ -1,40 +1,32 @@ Reticulum Network Stack ========== +> [!WARNING] +> A significant number of hastily launched, incorrect, dubious, directly harmful and, in most cases, entirely LLM-generated fakes of Reticulum implementations, "documentation", "guides" and user-facing applications are currently being marketed under polished, but ultimately misleading or outright deceptive claims. +> +> For more detailed information, see the relevant sections of the [Brandolini's Reference](https://reticulum.network/manual/brandolinis.html) chapter of the manual. Known good community implementations are listed in the [Community Implementations](#community-implementations) section of this readme. For software and projects recognized by the Reticulum community, see the [Programs Using Reticulum](https://reticulum.network/manual/software.html) chapter of the manual. +> +> Machine-generated content derived from the RNS source code or documentation (such as "implementations", "guides" for sale, et cetera), are in several, well-documented cases violating the open source licenses that granted rights of copying and distribution. +> +> Any claimed assertion of copyright or grant of license (Apache, GPL, et cetera) that such projects are making are [void grants](https://reticulum.network/manual/brandolinis.html#void-grants-legal-foundations-of-machine-generated-code). Both the violators themselves, and all downstream projects using the infringing derivatives, are **directly** and personally liable for the legal consequences. +> +> Do **not** use these "projects", they are a hazard to the entire ecosystem we have been carefully building over the last ten years. +

*This repository is [a public mirror](./MIRROR.md). All development is happening elsewhere.* To understand the foundational philosophy and goals of this system, read the [Zen of Reticulum](Zen%20of%20Reticulum.md). -Reticulum is the cryptography-based networking stack for building local and wide-area -networks with readily available hardware. It can operate even with very high latency -and extremely low bandwidth. Reticulum allows you to build wide-area networks -with off-the-shelf tools, and offers end-to-end encryption and connectivity, -initiator anonymity, autoconfiguring cryptographically backed multi-hop -transport, efficient addressing, unforgeable delivery acknowledgements and -more. +Reticulum is the cryptography-based networking stack for building local and wide-area networks with readily available hardware. It can operate even with very high latency and extremely low bandwidth. Reticulum allows you to build wide-area networks with off-the-shelf tools, and offers end-to-end encryption and connectivity, initiator anonymity, autoconfiguring cryptographically backed multi-hop transport, efficient addressing, unforgeable delivery acknowledgements and more. -The vision of Reticulum is to allow anyone to be their own network operator, -and to make it cheap and easy to cover vast areas with a myriad of independent, -inter-connectable and autonomous networks. Reticulum **is not** *one* network. -It is **a tool** for building *thousands of networks*. Networks without -kill-switches, surveillance, censorship and control. Networks that can freely -interoperate, associate and disassociate with each other, and require no -central oversight. Networks for human beings. *Networks for the people*. +The vision of Reticulum is to allow anyone to be their own network operator, and to make it cheap and easy to cover vast areas with a myriad of independent, inter-connectable and autonomous networks. Reticulum **is not** *one* network. It is **a tool** for building *thousands of networks*. Networks without kill-switches, surveillance, censorship and control. Networks that can freely interoperate, associate and disassociate with each other, and require no central oversight. Networks for human beings. *Networks for the people*. -Reticulum is a complete networking stack, and does not rely on IP or higher -layers, but it is possible to use IP as the underlying carrier for Reticulum. -It is therefore trivial to tunnel Reticulum over the Internet or private IP -networks. +Reticulum is a complete networking stack, and does not rely on IP or higher layers, but it is possible to use IP as the underlying carrier for Reticulum. It is therefore trivial to tunnel Reticulum over the Internet or private IP networks. -Having no dependencies on traditional networking stacks frees up overhead that -has been used to implement a networking stack built directly on cryptographic -principles, allowing resilience and stable functionality, even in open and -trustless networks. +Having no dependencies on traditional networking stacks frees up overhead that has been used to implement a networking stack built directly on cryptographic principles, allowing resilience and stable functionality, even in open and trustless networks. -No kernel modules or drivers are required. Reticulum runs completely in -userland, and can run on practically any system that runs Python 3. +No kernel modules or drivers are required. Reticulum runs completely in userland, and can run on practically any system that runs Python 3. ## Read The Manual The full documentation for Reticulum is available at [markqvist.github.io/Reticulum/manual/](https://markqvist.github.io/Reticulum/manual/). @@ -78,12 +70,20 @@ For more info, see [reticulum.network](https://reticulum.network/) and [the FAQ - Low cost of keeping links open at only 0.44 bits per second - Reliable sequential delivery with Channel and Buffer mechanisms +## Community Resources + +The references listed here are not run, managed or moderated by the Reticulum project or its maintainer. They are provided by dedicated, independent volunteers in the community, for the benefit of anyone interested in learning more about Reticulum. + +- [Reticulum Community Wiki](https://reticulum.miraheze.org/wiki) +- [RNS Recipes](https://rns.recipes/) +- [RNS Moscow](https://rns.moscow/) +- [RMAP.world](https://rmap.world/) + +If you find anything that is no longer accurate, incorrect or simply not quite up to date, do not demand or complain towards the maintainers of these resources. Instead, take the task upon yourself to help out and improve things by working on, and offering the contributions you would like to see, like the creators of the above did themselves. + ## Reference Implementation -The Python code in this repository is the Reference Implementation of Reticulum. -The Reticulum Protocol is defined entirely and authoritatively by this reference -implementation, and its associated manual. It is maintained by Mark Qvist, -identified by the Reticulum Identity ``. +The Python code in this repository is the Reference Implementation of Reticulum. The Reticulum Protocol is defined entirely and authoritatively by this reference implementation, and its associated manual. It is maintained by Mark Qvist, identified by the Reticulum Identity ``. No second-order protocol specification derivatives currently do, or will ever exist. You can't get a better specification than one that is executable, functional, testable, deployed and operating 24/7 across the planet. @@ -91,18 +91,39 @@ There is not, and never will be a separate, derived "formal spec", "RFC" or anyt **The reference implementation *is* the final, authoritative specification.** -Compatibility with the Reticulum Protocol is defined as having full interoperability, -and sufficient functional parity with this reference implementation. Any specific protocol -implementation that achieves this is Reticulum. Any that does not is not Reticulum. +Compatibility with the Reticulum Protocol is defined as having full interoperability, and sufficient functional parity with this reference implementation. Any specific protocol implementation that achieves this is Reticulum. Any that does not is not Reticulum. The reference implementation is licensed under the Reticulum License. The Reticulum Protocol was dedicated to the Public Domain in 2016. +## Community Implementations + +The implementations listed here have demonstrated wire-compatibility, sufficient feature parity, sensible security and development practices, long-term commitment and care for implementation quality. Additionally, they have a track record of at least 18 months of active development. + +Most importantly, their developers and maintainers are recognized by the community to actually know what they are doing, and as having a commitment to improving the overall Reticulum ecosystem. + +- [Chad Atterman's](https://github.com/attermann) [microReticulum](https://github.com/attermann/microReticulum/) is a C++ implementation targeting 32-bit micro-controllers. +- [Quad4's](https://quad4.io/) [Reticulum-Go](https://reticulum-go.quad4.io/) is a Go implementation targeting both desktop, mobile and embedded systems. + +*If you are the maintainer of an implementation not listed above, and believe that it deserves inclusion by following the same standards of rigor and commitment, your proposal will be welcomed.* + +--- + +**Warning!** A significant number of hastily launched, incorrect, dubious, directly harmful and, in most cases, entirely LLM-generated fakes of Reticulum implementations (and user facing applications) are currently being marketed and pushed under polished, but ultimately misleading or outright deceptive claims. Most of these are either quick attention or money grabs, completely unreviewed, incompatible, without maintenance or human oversight, actively trying to fragment the community, or a combination thereof. + +--- + +For more extensive information on this topic, read the [Brandolini's Reference](https://reticulum.network/manual/brandolinis.html) chapter of the manual (for the legal foundations, see [Void Grants](https://reticulum.network/manual/brandolinis.html#void-grants-legal-foundations-of-machine-generated-code) specifically). The chapter is very long, very detailed, and is the polite, measured analysis, intended as an evolving, sectioned reference on these issues. + +If you would rather just have the short, unfiltered and quite angry version, which consists of an enacted response to one particular manifestation of the phenomenon as a whole, used as an example, you can read [Yes, I am Angry](docs/history/2026_09_18_Yes_I_am_Angry.md). It gets the same point across, in a very different language, if you can handle that sort of communication. + +The core Reticulum maintainers and developers **strongly advise against using any such "implementation"**. The [deceitful and self-serving behavior](https://reticulum.network/manual/brandolinis.html#a-persistent-but-fragile-triad) of a small number of either malintented, attention-seeking or incompetent individuals has caused significant [damage and waste of time and resources](https://reticulum.network/manual/brandolinis.html#intent-consequence) for both developers, node operators, users and the community and Reticulum project at large. + +We kindly, but urgently ask all users to excercise caution, common sense and healthy skepticism when [evaluating](https://reticulum.network/manual/brandolinis.html#evaluating-a-reticulum-implementation) the potential use of any implementation not listed above; and to accept that **choosing to do so regardless translates the responsibility for potential damage from an irresponsible or malicious individual onto yourself**. + ## Examples of Reticulum Applications -If you want to quickly get an idea of what Reticulum can do, take a look at the -[Programs Using Reticulum](https://reticulum.network/manual/software.html) -section of the manual, or the following resources: +If you want to quickly get an idea of what Reticulum can do, take a look at the [Programs Using Reticulum](https://reticulum.network/manual/software.html) section of the manual, or the following resources: - [LXMF](https://github.com/markqvist/lxmf) is a distributed, delay and disruption tolerant message transfer protocol built on Reticulum - The [LXST](https://github.com/markqvist/lxst) protocol and framework provides real-time audio and signals transport over Reticulum. It includes primitives and utilities for building voice-based applications and hardware devices, such as the `rnphone` program, that can be used to build hardware telephones. @@ -110,50 +131,27 @@ section of the manual, or the following resources: - The Android, Linux, macOS and Windows app [Sideband](https://github.com/markqvist/Sideband) has a graphical interface and many advanced features, such as file transfers, image and voice messages, real-time voice calls, a distributed telemetry system, mapping capabilities and full plugin extensibility. - [MeshChatX](https://git.quad4.io/RNS-Things/MeshChatX) is a full-featured LXMF client with many built-in tools and functionalities, that also supports image and voice messages, file transfers and voice calls. It also includes a built-in page browser for browsing Nomad Network nodes. - You can use the included [rnsh](https://reticulum.network/manual/using.html#the-rnsh-utility) program to establish remote shell sessions over Reticulum. +- The included [rngit](https://reticulum.network/manual/git.html) system provides a full solution for managing, hosting, collaborating on and interacting with Git repositories over Reticulum. ## Where can Reticulum be used? -Over practically any medium that can support at least a half-duplex channel -with greater throughput than 5 bits per second, and an MTU of 500 bytes. Data radios, -modems, LoRa radios, serial lines, AX.25 TNCs, amateur radio digital modes, -WiFi and Ethernet devices, free-space optical links, and similar systems are -all examples of the types of physical devices Reticulum can use. +Over practically any medium that can support at least a half-duplex channel with greater throughput than 5 bits per second, and an MTU of 500 bytes. Data radios, modems, LoRa radios, serial lines, AX.25 TNCs, amateur radio digital modes, WiFi and Ethernet devices, free-space optical links, and similar systems are all examples of the types of physical devices Reticulum can use. -An open-source LoRa-based interface called -[RNode](https://markqvist.github.io/Reticulum/manual/hardware.html#rnode) has -been designed specifically for use with Reticulum. It is possible to build -yourself, or it can be purchased as a complete transceiver that just needs a -USB connection to the host. +An open-source LoRa-based interface called [RNode](https://markqvist.github.io/Reticulum/manual/hardware.html#rnode) has been designed specifically for use with Reticulum. It is possible to build yourself, or it can be purchased as a complete transceiver that just needs a USB, WiFi or Bluetooth connection to the host. -Reticulum can also be encapsulated over existing IP networks, so there's -nothing stopping you from using it over wired Ethernet, your local WiFi network -or the Internet, where it'll work just as well. In fact, one of the strengths -of Reticulum is how easily it allows you to connect different mediums into a -self-configuring, resilient and encrypted mesh, using any available mixture of -available infrastructure. +Reticulum can also be encapsulated over existing IP networks, so there's nothing stopping you from using it over wired Ethernet, your local WiFi network or the Internet, where it'll work just as well. In fact, one of the strengths of Reticulum is how easily it allows you to connect different mediums into a self-configuring, resilient and encrypted mesh, using any available mixture of available infrastructure. -As an example, it's possible to set up a Raspberry Pi connected to both a LoRa -radio, a packet radio TNC and a WiFi network. Once the interfaces are -configured, Reticulum will take care of the rest, and any device on the WiFi -network can communicate with nodes on the LoRa and packet radio sides of the -network, and vice versa. +As an example, it's possible to set up a Raspberry Pi connected to both a LoRa radio, a packet radio TNC and a WiFi network. Once the interfaces are configured, Reticulum will take care of the rest, and any device on the WiFi network can communicate with nodes on the LoRa and packet radio sides of the network, and vice versa. ## How do I get started? -The best way to get started with the Reticulum Network Stack depends on what -you want to do. For full details and examples, have a look at the -[Getting Started Fast](https://markqvist.github.io/Reticulum/manual/gettingstartedfast.html) -section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/). +The best way to get started with the Reticulum Network Stack depends on what you want to do. For full details and examples, have a look at the [Getting Started Fast](https://markqvist.github.io/Reticulum/manual/gettingstartedfast.html) section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/). -To simply install Reticulum and related utilities on your system, the easiest way is via `pip`. -You can then start any program that uses Reticulum, or start Reticulum as a system service with -[the rnsd utility](https://markqvist.github.io/Reticulum/manual/using.html#the-rnsd-utility). +To simply install Reticulum and related utilities on your system, the easiest way is via `pip`. You can then start any program that uses Reticulum, or start Reticulum as a system service with [the rnsd utility](https://markqvist.github.io/Reticulum/manual/using.html#the-rnsd-utility). ```bash pip install rns ``` -If you are using an operating system that blocks normal user package installation via `pip`, -you can return `pip` to normal behaviour by editing the `~/.config/pip/pip.conf` file, -and adding the following directive in the `[global]` section: +If you are using an operating system that blocks normal user package installation via `pip`, you can return `pip` to normal behaviour by editing the `~/.config/pip/pip.conf` file, and adding the following directive in the `[global]` section: ```text [global] @@ -166,23 +164,14 @@ Alternatively, you can use the `pipx` tool to install Reticulum in an isolated e pipx install rns ``` -When first started, Reticulum will create a default configuration file, -providing basic connectivity to other Reticulum peers that might be locally -reachable. The default config file contains a few examples, and references for -creating a more complex configuration. +When first started, Reticulum will create a default configuration file, providing basic connectivity to other Reticulum peers that might be locally reachable. The default config file contains a few examples, and references for creating a more complex configuration. If you have an old version of `pip` on your system, you may need to upgrade it first with `pip install pip --upgrade`. If you no not already have `pip` installed, you can install it using the package manager of your system with `sudo apt install python3-pip` or similar. -For more detailed examples on how to expand communication over many mediums such -as packet radio or LoRa, serial ports, or over fast IP links and the Internet using -the UDP and TCP interfaces, take a look at the [Supported Interfaces](https://markqvist.github.io/Reticulum/manual/interfaces.html) -section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/). +For more detailed examples on how to expand communication over many mediums such as packet radio or LoRa, serial ports, or over fast IP links and the Internet using the UDP and TCP interfaces, take a look at the [Supported Interfaces](https://markqvist.github.io/Reticulum/manual/interfaces.html) section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/). ## Included Utilities -Reticulum includes a range of useful utilities for managing your networks, -viewing status and information, and other tasks. You can read more about these -programs in the [Included Utility Programs](https://markqvist.github.io/Reticulum/manual/using.html#included-utility-programs) -section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/). +Reticulum includes a range of useful utilities for managing your networks, viewing status and information, and other tasks. You can read more about these programs in the [Included Utility Programs](https://markqvist.github.io/Reticulum/manual/using.html#included-utility-programs) section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/). - The system daemon `rnsd` for running Reticulum as an always-available service - An interface status utility called `rnstatus`, that displays information about interfaces @@ -195,19 +184,13 @@ section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/) - The `rngit` program provides a full multi-repository Git node for serving repositories over Reticulum - The included `git-remote-rns` helper allows you to interact with Git repositories over Reticulum -All tools, including `rnx` and `rncp`, work reliably and well even over very -low-bandwidth links like LoRa or Packet Radio. For full-featured remote shells -over Reticulum, also have a look at the [rnsh](https://github.com/acehoss/rnsh) -program. +All tools, including `rnx` and `rncp`, work reliably and well even over very low-bandwidth links like LoRa or Packet Radio. For full-featured remote shells over Reticulum, also have a look at the [rnsh](https://github.com/acehoss/rnsh) program. ## Supported interface types and devices -Reticulum implements a range of generalised interface types that covers most of -the communications hardware that Reticulum can run over. If your hardware is -not supported, it's [simple to implement a custom interface module](https://markqvist.github.io/Reticulum/manual/interfaces.html#custom-interfaces). +Reticulum implements a range of generalised interface types that covers most of the communications hardware that Reticulum can run over. If your hardware is not supported, it's [simple to implement a custom interface module](https://markqvist.github.io/Reticulum/manual/interfaces.html#custom-interfaces). -Pull requests for custom interfaces are gratefully accepted, provided they are -generally useful and well-tested in real-world usage. +Contributions of custom interfaces are gratefully accepted, provided they are generally useful and well-tested in real-world usage. Currently, the following built-in interfaces are supported: @@ -222,62 +205,42 @@ Currently, the following built-in interfaces are supported: - Custom hardware via stdio or pipes ## Performance -Reticulum targets a *very* wide usable performance envelope, but prioritises -functionality and performance on low-bandwidth mediums. The goal is to -provide a dynamic performance envelope from 250 bits per second, to 1 gigabit -per second on normal hardware. +*All performance numbers here assume `rnsd` running in fully interpreted Python mode, limited to a single CPU core.* -Currently, the usable performance envelope is approximately 150 bits per second -to 500 megabits per second, with physical mediums faster than that not being -saturated. Performance beyond the current level is intended for future -upgrades, but not highly prioritised at this point in time. +Reticulum targets a *very* wide usable performance envelope, but prioritises functionality and performance on low-bandwidth mediums. The goal is to provide a dynamic performance envelope from 100 bits per second, to 10 gigabits per second on normal hardware. + +Currently, the on-network, usable performance envelope is approximately 150 bits per second to 1 gigabit per second on modest hardware. Real-world performance will vary widely with the speed of your system, availability of cryptographic hardware acceleration, and other factors. + +Raw routing throughput for a transport node hosted on a Raspberry Pi 5 is approximately 5 gigabits per second. Systems with modern crypto hardware acceleration can achieve transport throughput of 15 gigabits per second and higher. + +While the reference implementation is perfectly capable of reaching 100+ Gbps, by utilizing multiple CPU cores and vectorized transport, performance beyond the current level is not higly prioritised, since RNS is already able to saturate available physical medium bandwidth in almost all real-world situations. + +The primary objectives for RNS are *reliability*, *correctness*, *security*, *proper traffic management* and *actually practical performance*, not hollow on-paper "benchmarks" with little to no bearing on real-world usability. + +All alternative-implementation maintainers are *highly* encouraged to adopt a similar approach, and especially to focus on getting their implementations working properly and reliably before publishing empirically dubious or factually wrong performance claims. ## Current Status -All core protocol features are implemented and functioning, but additions will -probably occur as real-world use is explored and understood. The API and wire-format -can be considered stable. +All core protocol features are implemented and functioning, but additions will probably occur as real-world use is explored and understood. The API and wire-format can be considered stable. ## Dependencies -The installation of the default `rns` package requires only two external dependencies, listed -below. Almost all systems and distributions have readily available packages for -these dependencies, and when the `rns` package is installed with `pip`, they -will be downloaded and installed as well. +The installation of the default `rns` package requires only two external dependencies, listed below. Almost all systems and distributions have readily available packages for these dependencies, and when the `rns` package is installed with `pip`, they will be downloaded and installed as well. - [PyCA/cryptography](https://github.com/pyca/cryptography) - [pyserial](https://github.com/pyserial/pyserial) -On more unusual systems, and in some rare cases, it might not be possible to -install or even compile one or more of the above modules. In such situations, -you can use the `rnspure` package instead, which require no external -dependencies for installation. Please note that the contents of the `rns` and -`rnspure` packages are *identical*. The only difference is that the `rnspure` -package lists no dependencies required for installation. +On more unusual systems, and in some rare cases, it might not be possible to install or even compile one or more of the above modules. In such situations, you can use the `rnspure` package instead, which require no external dependencies for installation. Please note that the contents of the `rns` and `rnspure` packages are *identical*. The only difference is that the `rnspure` package lists no dependencies required for installation. -No matter how Reticulum is installed and started, it will load external -dependencies only if they are *needed* and *available*. If for example you want -to use Reticulum on a system that cannot support -[pyserial](https://github.com/pyserial/pyserial), it is perfectly possible to -do so using the `rnspure` package, but Reticulum will not be able to use -serial-based interfaces. All other available modules will still be loaded when -needed. +No matter how Reticulum is installed and started, it will load external dependencies only if they are *needed* and *available*. If for example you want to use Reticulum on a system that cannot support [pyserial](https://github.com/pyserial/pyserial), it is perfectly possible to do so using the `rnspure` package, but Reticulum will not be able to use serial-based interfaces. All other available modules will still be loaded when needed. -**Please Note!** If you use the `rnspure` package to run Reticulum on systems -that do not support [PyCA/cryptography](https://github.com/pyca/cryptography), -it is important that you read and understand the [Cryptographic -Primitives](#cryptographic-primitives) section of this document. +**Please Note!** If you use the `rnspure` package to run Reticulum on systems that do not support [PyCA/cryptography](https://github.com/pyca/cryptography), it is important that you read and understand the [Cryptographic Primitives](#cryptographic-primitives) section of this document. ## Bootstrapping Connectivity -Reticulum is not a service you subscribe to, nor is it a single global network you "join". -Reticulum provides functionality for discovering available public interfaces -over the network itself, and the broader community has provided various directories -of publicly available entrypoints to bootstrap connectivity. +Reticulum is not a service you subscribe to, nor is it a single global network you "join". Reticulum provides functionality for discovering available public interfaces over the network itself, and the broader community has provided various directories of publicly available entrypoints to bootstrap connectivity. To learn how to establish initial connectivity over Reticulum, read the [Bootstrapping Connectivity](https://reticulum.network/manual/gettingstartedfast.html#bootstrapping-connectivity) section of the manual. -If you already have a general idea of how this works, you can use community-run -sites such as [directory.rns.recipes](https://directory.rns.recipes/) and [rmap.world](https://rmap.world) -to find interface definitions for initial connectivity to the global distributed Reticulum backbone. +If you already have a general idea of how this works, you can use community-run sites such as [directory.rns.recipes](https://directory.rns.recipes/) and [rmap.world](https://rmap.world) to find interface definitions for initial connectivity to the global distributed Reticulum backbone. ## Public Testnet ***Important!** Historically, a developer-targeted testnet was made available by the Reticulum project itself. As the amount of global Reticulum nodes and entrypoints have grown to a substantial quantity, this public testnet, including the Amsterdam Testnet entrypoint, has now been decommissioned. If your still have instances that relied on this entrypoint for connectivity, transition to using the distributed backbone instead. Reticulum now includes a full on-network interface discovery and connectivity bootstrapping system. Read the [Bootstrapping Connectivity](https://reticulum.network/manual/gettingstartedfast.html#bootstrapping-connectivity) section of the manual for pointers.* @@ -302,17 +265,11 @@ For this to be possible, I need your help. Please support the continued developm - Ko-Fi: https://ko-fi.com/markqvist ## Cryptographic Primitives -Reticulum uses a simple suite of efficient, strong and well-tested cryptographic -primitives, with widely available implementations that can be used both on -general-purpose CPUs and on microcontrollers. +Reticulum uses a simple suite of efficient, strong and well-tested cryptographic primitives, with widely available implementations that can be used both on general-purpose CPUs and on microcontrollers. -One of the primary considerations for choosing this particular set of primitives is -that they can be implemented *safely* with relatively few pitfalls, on practically -all current computing platforms. +One of the primary considerations for choosing this particular set of primitives is that they can be implemented *safely* with relatively few pitfalls, on practically all current computing platforms. -The primitives listed here **are authoritative**. Anything claiming to be Reticulum, -but not using these exact primitives **is not** Reticulum, and possibly an -intentionally compromised or weakened clone. The utilised primitives are: +The primitives listed here **are authoritative**. Anything claiming to be Reticulum, but not using these exact primitives **is not** Reticulum, and possibly an intentionally compromised or weakened clone. The utilised primitives are: - Reticulum Identity Keys are 512-bit Curve25519 keysets - A 256-bit Ed25519 key for signatures @@ -327,13 +284,7 @@ intentionally compromised or weakened clone. The utilised primitives are: - SHA-256 - SHA-512 -In the default installation configuration, the `X25519`, `Ed25519`, -and `AES-256-CBC` primitives are provided by [OpenSSL](https://www.openssl.org/) -(via the [PyCA/cryptography](https://github.com/pyca/cryptography) package). -The hashing functions `SHA-256` and `SHA-512` are provided by the standard -Python [hashlib](https://docs.python.org/3/library/hashlib.html). The `HKDF`, -`HMAC`, `Token` primitives, and the `PKCS7` padding function are always -provided by the following internal implementations: +In the default installation configuration, the `X25519`, `Ed25519`, and `AES-256-CBC` primitives are provided by [OpenSSL](https://www.openssl.org/) (via the [PyCA/cryptography](https://github.com/pyca/cryptography) package). The hashing functions `SHA-256` and `SHA-512` are provided by the standard Python [hashlib](https://docs.python.org/3/library/hashlib.html). The `HKDF`, `HMAC`, `Token` primitives, and the `PKCS7` padding function are always provided by the following internal implementations: - [HKDF.py](RNS/Cryptography/HKDF.py) - [HMAC.py](RNS/Cryptography/HMAC.py) @@ -341,39 +292,18 @@ provided by the following internal implementations: - [PKCS7.py](RNS/Cryptography/PKCS7.py) -Reticulum also includes a complete implementation of all necessary primitives -in pure Python. If OpenSSL and PyCA are not available on the system when -Reticulum is started, Reticulum will instead use the internal pure-python -primitives. A trivial consequence of this is performance, with the OpenSSL -backend being *much* faster. The most important consequence however, is the -potential loss of security by using primitives that has not seen the same -amount of scrutiny, testing and review as those from OpenSSL. +Reticulum also includes a complete implementation of all necessary primitives in pure Python. If OpenSSL and PyCA are not available on the system when Reticulum is started, Reticulum will instead use the internal pure-python primitives. A trivial consequence of this is performance, with the OpenSSL backend being *much* faster. The most important consequence however, is the potential loss of security by using primitives that has not seen the same amount of scrutiny, testing and review as those from OpenSSL. -Please note that by default, installing Reticulum will **require** OpenSSL and -PyCA to also be automatically installed if not already available. It is only -possible to use the pure-python primitives if this requirement is specifically -overridden by the user, for example by installing the `rnspure` package instead -of the normal `rns` package, or by running directly from local source-code. +Please note that by default, installing Reticulum will **require** OpenSSL and PyCA to also be automatically installed if not already available. It is only possible to use the pure-python primitives if this requirement is specifically overridden by the user, for example by installing the `rnspure` package instead of the normal `rns` package, or by running directly from local source-code. -If you want to use the internal pure-python primitives, it is **highly -advisable** that you have a good understanding of the risks that this pose, and -make an informed decision on whether those risks are acceptable to you. +If you want to use the internal pure-python primitives, it is **highly advisable** that you have a good understanding of the risks that this pose, and make an informed decision on whether those risks are acceptable to you. -Reticulum is relatively young software, and should be considered as such. While -it has been built with cryptography best-practices very foremost in mind, it -_has not_ been externally security audited, and there could very well be -privacy or security breaking bugs. If you want to help out, or help sponsor an -audit, please do get in touch. +Having been in development for ten, and wider deployment for around five years, Reticulum is relatively young software, and should be considered as such. While it has been carefully built with cryptography best-practices very foremost in mind, there could very well still be privacy or security breaking bugs. ## Acknowledgements & Credits -Reticulum can only exist because of the mountain of Open Source work it was -built on top of, the contributions of everyone involved, and everyone that has -supported the project through the years. To everyone who has helped, thank you -so much. +Reticulum can only exist because of the mountain of Open Source work it was built on top of, the contributions of everyone involved, and everyone that has supported the project through the years. To everyone who has helped, thank you so much. -A number of other modules and projects are either part of, or used by -Reticulum. Sincere thanks to the authors and contributors of the following -projects: +A number of other modules and projects are either part of, or used by Reticulum. Sincere thanks to the authors and contributors of the following projects: - [PyCA/cryptography](https://github.com/pyca/cryptography), *BSD License* - [Pure-25519](https://github.com/warner/python-pure25519) by [Brian Warner](https://github.com/warner), *MIT License* diff --git a/README.mu b/README.mu index 2d361909..c64a7a50 100644 --- a/README.mu +++ b/README.mu @@ -4,6 +4,8 @@ To understand the foundational philosophy and goals of this system, read the `_` Reticulum is the cryptography-based networking stack for building local and wide-area networks with readily available hardware. It can operate even with very high latency and extremely low bandwidth. Reticulum allows you to build wide-area networks with off-the-shelf tools, and offers end-to-end encryption and connectivity, initiator anonymity, autoconfiguring cryptographically backed multi-hop transport, efficient addressing, unforgeable delivery acknowledgements and more. +`(RNS Logo`w=18`a=c`:/media/reticulum/reticulum/HEAD/docs/source/graphics/rns_logo_256.webp) + The vision of Reticulum is to allow anyone to be their own network operator, and to make it cheap and easy to cover vast areas with a myriad of independent, inter-connectable and autonomous networks. Reticulum `!is not`! `*one`* network. It is `!a tool`! for building `*thousands of networks`*. Networks without kill-switches, surveillance, censorship and control. Networks that can freely interoperate, associate and disassociate with each other, and require no central oversight. Networks for human beings. `*Networks for the people`*. Reticulum is a complete networking stack, and does not rely on IP or higher layers, but it is possible to use IP as the underlying carrier for Reticulum. It is therefore trivial to tunnel Reticulum over the Internet or private IP networks. @@ -170,9 +172,19 @@ Currently, the following built-in interfaces are supported: >> Performance -Reticulum targets a `*very`* wide usable performance envelope, but prioritises functionality and performance on low-bandwidth mediums. The goal is to provide a dynamic performance envelope from 250 bits per second, to 1 gigabit per second on normal hardware. +`*All performance numbers here assume `B333rnsd`b running in fully interpreted Python mode, limited to a single CPU core.`* -Currently, the usable performance envelope is approximately 150 bits per second to 500 megabits per second, with physical mediums faster than that not being saturated. Performance beyond the current level is intended for future upgrades, but not highly prioritised at this point in time. +Reticulum targets a `*very`* wide usable performance envelope, but prioritises functionality and performance on low-bandwidth mediums. The goal is to provide a dynamic performance envelope from 100 bits per second, to 10 gigabits per second on normal hardware. + +Currently, the on-network, usable performance envelope is approximately 150 bits per second to 1 gigabit per second on modest hardware. Real-world performance will vary widely with the speed of your system, availability of cryptographic hardware acceleration, and other factors. + +Raw routing throughput for a transport node hosted on a Raspberry Pi 5 is approximately 4 gigabits per second. Systems with modern crypto hardware acceleration can achieve transport throughput of 15 gigabits per second and higher. + +While the reference implementation is perfectly capable of reaching 100+ Gbps, by utilizing multiple CPU cores and vectorized transport, performance beyond the current level is not higly prioritised, since RNS is already able to saturate available physical medium bandwidth in almost all real-world situations. + +The primary objectives for RNS are `*reliability`*, `*correctness`*, `*security`*, `*proper traffic management`* and `*actually practical performance`*, not hollow on-paper "benchmarks" with little to no bearing on real-world usability. + +All alternative-implementation maintainers are `*highly`* encouraged to adopt a similar approach, and especially to focus on getting their implementations working properly before publishing empirically dubious or factually wrong performance claims. >> Current Status @@ -256,7 +268,7 @@ Please note that by default, installing Reticulum will `!require`! OpenSSL and P If you want to use the internal pure-python primitives, it is `!highly advisable`! that you have a good understanding of the risks that this pose, and make an informed decision on whether those risks are acceptable to you. -Reticulum is relatively young software, and should be considered as such. While it has been built with cryptography best-practices very foremost in mind, it _has not_ been externally security audited, and there could very well be privacy or security breaking bugs. If you want to help out, or help sponsor an audit, please do get in touch. +Having been in development for ten, and wider deployment for around five years, Reticulum is relatively young software, and should be considered as such. While it has been carefully built with cryptography best-practices very foremost in mind, there could very well still be privacy or security breaking bugs. >> Acknowledgements & Credits diff --git a/RNS/Discovery.py b/RNS/Discovery.py index 57e3d875..7dbf09c6 100644 --- a/RNS/Discovery.py +++ b/RNS/Discovery.py @@ -1,3 +1,33 @@ +# Reticulum License +# +# Copyright (c) 2016-2026 Mark Qvist +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# - The Software shall not be used in any kind of system which includes amongst +# its functions the ability to purposefully do harm to human beings. +# +# - The Software shall not be used, directly or indirectly, in the creation of +# an artificial intelligence, machine learning or language model training +# dataset, including but not limited to any use that contributes to the +# training or development of such a model or algorithm. +# +# - The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + import os import re import RNS @@ -204,8 +234,8 @@ class InterfaceAnnouncer(): info[MODULATION] = self.sanitize(interface.discovery_modulation) if interface.discovery_publish_ifac == True: - info[IFAC_NETNAME] = self.sanitize(interface.ifac_netname) - info[IFAC_NETKEY] = self.sanitize(interface.ifac_netkey) + if interface.ifac_netname: info[IFAC_NETNAME] = self.sanitize(interface.ifac_netname) + if interface.ifac_netkey: info[IFAC_NETKEY] = self.sanitize(interface.ifac_netkey) packed = msgpack.packb(info) infohash = RNS.Identity.full_hash(packed) @@ -315,6 +345,8 @@ class InterfaceAnnounceHandler: if INTERFACE_TYPE in unpacked: interface_type = unpacked[INTERFACE_TYPE] name = self.sanitize_name(unpacked[NAME]) + impl_name = unpacked[TRANSPORT_IMPL] if TRANSPORT_IMPL in unpacked else None + impl_version = unpacked[TRANSPORT_VERS] if TRANSPORT_VERS in unpacked else None if type(unpacked[TRANSPORT]) != bool: raise ValueError("Invalid data in transport field of announce") if type(unpacked[LATITUDE]) not in [type(None), float]: raise ValueError("Invalid data in latitude field of announce") @@ -329,6 +361,8 @@ class InterfaceAnnounceHandler: raise ValueError("Invalid data in reachable_on field of announce") info = {"type": interface_type, + "impl_name": impl_name, + "version": impl_version, "transport": unpacked[TRANSPORT], "name": name or f"Discovered {interface_type}", "received": time.time(), @@ -341,8 +375,8 @@ class InterfaceAnnounceHandler: "longitude": unpacked[LONGITUDE], "height": unpacked[HEIGHT]} - if IFAC_NETNAME in unpacked: info["ifac_netname"] = str(unpacked[IFAC_NETNAME]) - if IFAC_NETKEY in unpacked: info["ifac_netkey"] = str(unpacked[IFAC_NETKEY]) + if IFAC_NETNAME in unpacked and unpacked[IFAC_NETNAME] and type(unpacked[IFAC_NETNAME]) == str: info["ifac_netname"] = str(unpacked[IFAC_NETNAME]) + if IFAC_NETKEY in unpacked and unpacked[IFAC_NETKEY] and type(unpacked[IFAC_NETKEY]) == str: info["ifac_netkey"] = str(unpacked[IFAC_NETKEY]) if interface_type in ["BackboneInterface", "TCPServerInterface"]: backbone_support = not RNS.vendor.platformutils.is_windows() and not RNS.vendor.platformutils.is_darwin() @@ -371,7 +405,7 @@ class InterfaceAnnounceHandler: cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else "" cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else "" cfg_identity_str = f"\n transport_identity = {cfg_identity}" - info["config_entry"] = f"[[{cfg_name}]]\n type = I2PInterface\n enabled = yes\n peers = {cfg_remote}{cfg_identity_str}{cfg_netname_str}{cfg_netkey_str}" + info["config_entry"] = f"[[{cfg_name}]]\n type = I2PInterface\n enabled = yes\n peers = {cfg_remote}.b32.i2p{cfg_identity_str}{cfg_netname_str}{cfg_netkey_str}" if interface_type == "RNodeInterface": info["frequency"] = unpacked[FREQUENCY] @@ -446,13 +480,17 @@ class InterfaceDiscovery(): STATUS_UNKNOWN = 100 STATUS_AVAILABLE = 1000 STATUS_CODE_MAP = {"available": STATUS_AVAILABLE, "unknown": STATUS_UNKNOWN, "stale": STATUS_STALE} - AUTOCONNECT_TYPES = ["BackboneInterface", "TCPServerInterface"] + AUTOCONNECT_TYPES = ["BackboneInterface"] DISCOVERABLE_TYPES = ["BackboneInterface", "TCPServerInterface", "I2PInterface", "RNodeInterface", "WeaveInterface", "KISSInterface"] + AUTOCONNECT_IMPLS = ["RNS"] + AUTOCONNECT_MIN_V = "1.5.2" + AC_TRANSPORT_MODE = RNS.Interfaces.Interface.Interface.MODE_GATEWAY AC_GRAVITY = 0 discovery_lock = Lock() + autoconnect_lock = Lock() def __init__(self, required_value=InterfaceAnnouncer.DEFAULT_STAMP_VALUE, callback=None, discover_interfaces=True): if not required_value: required_value = InterfaceAnnouncer.DEFAULT_STAMP_VALUE @@ -498,7 +536,16 @@ class InterfaceDiscovery(): should_remove = False heard_delta = now-info["last_heard"] info["name"] = InterfaceAnnounceHandler.sanitize_name(info["name"]) - + + # TODO: Temporary measure to sanitize invalidly persisted "None" values + # for incorrect IFAC parameters published due to unguarded nonsensical + # node-side configuration. Potentially remove once nodes upgrade to RNS + # versions that guard against the configuration mismatch. + try: + if "ifac_netname" in info and info["ifac_netname"] == "None": info.pop("ifac_netname") + if "ifac_netkey" in info and info["ifac_netkey"] == "None": info.pop("ifac_netkey") + except Exception as e: RNS.log(f"Error while sanitizing discovery info: {e}", RNS.LOG_ERROR) + if heard_delta > self.THRESHOLD_REMOVE: should_remove = True elif not "transport_id" in info or not info["transport_id"]: should_remove = True elif not "network_id" in info or not info["network_id"]: should_remove = True @@ -544,11 +591,13 @@ class InterfaceDiscovery(): interface_type = info["type"] discovery_hash = info["discovery_hash"] discovered_type = info["type"] + has_impl_info = "impl_name" in info and "version" in info and info["impl_name"] and info["version"] + version_str = f" ({info['impl_name']} {info['version']})" if has_impl_info else " (unknown implementation)" if not discovered_type in self.DISCOVERABLE_TYPES: return hops = info["hops"]; ms = "" if hops == 1 else "s" filename = RNS.hexrep(discovery_hash, delimit=False) filepath = os.path.join(self.storagepath, filename) - RNS.log(f"Discovered {interface_type} {hops} hop{ms} away with stamp value {value}: {name}", RNS.LOG_DEBUG) + RNS.log(f"Discovered {interface_type}{version_str} {hops} hop{ms} away with stamp value {value}: {name}", RNS.LOG_DEBUG) with self.discovery_lock: if not os.path.isfile(filepath): try: @@ -616,22 +665,27 @@ class InterfaceDiscovery(): autoconnected_interfaces = self.autoconnect_count() for interface in self.monitored_interfaces: try: - if interface.online: - online_interfaces += 1 - if hasattr(interface, "autoconnect_down") and interface.autoconnect_down != None: - RNS.log(f"Auto-discovered interface {interface} reconnected") - interface.autoconnect_down = None + if not interface in RNS.Transport.interfaces: + RNS.log(f"A monitored auto-connected interface was manually detached, removing from monitoring", RNS.LOG_DEBUG) + detached_interfaces.append(interface) else: - if not hasattr(interface, "autoconnect_down") or interface.autoconnect_down == None: - RNS.log(f"Auto-discovered interface {interface} disconnected", RNS.LOG_DEBUG) - interface.autoconnect_down = time.time() + if interface.online: + online_interfaces += 1 + if hasattr(interface, "autoconnect_down") and interface.autoconnect_down != None: + RNS.log(f"Auto-discovered interface {interface} reconnected") + interface.autoconnect_down = None else: - down_for = time.time()-interface.autoconnect_down - if down_for >= self.detach_threshold: - RNS.log(f"Auto-discovered interface {interface} has been down for {RNS.prettytime(down_for)}, detaching", RNS.LOG_DEBUG) - detached_interfaces.append(interface) + if not hasattr(interface, "autoconnect_down") or interface.autoconnect_down == None: + RNS.log(f"Auto-discovered interface {interface} disconnected", RNS.LOG_DEBUG) + interface.autoconnect_down = time.time() + + else: + down_for = time.time()-interface.autoconnect_down + if down_for >= self.detach_threshold: + RNS.log(f"Auto-discovered interface {interface} has been down for {RNS.prettytime(down_for)}, detaching", RNS.LOG_DEBUG) + detached_interfaces.append(interface) except Exception as e: RNS.log(f"Error while checking auto-connected interface state for {interface}: {e}", RNS.LOG_ERROR) @@ -665,8 +719,10 @@ class InterfaceDiscovery(): RNS.log(f"Error while de-registering auto-connected interface from transport: {e}", RNS.LOG_ERROR) def teardown_interface(self, interface): - interface.detach() - RNS.Transport.remove_interface(interface) + if interface in RNS.Transport.interfaces: + was_detached = RNS.Reticulum.get_instance()._detach_interface(interface.name, internal_forced=True) + if not was_detached: RNS.log(f"Detach of auto-connected interface {interface} did not succeed", RNS.LOG_ERROR) + if interface in self.monitored_interfaces: self.monitored_interfaces.remove(interface) def autoconnect_count(self): @@ -713,6 +769,26 @@ class InterfaceDiscovery(): return exists + def autoconnect_interface_name(self, name): + names = {interface.name for interface in RNS.Transport.interfaces} + if not name in names: return name + else: + n = 2; seq_name = f"{name} ({n})" + while seq_name in names: + n += 1; seq_name = f"{name} ({n})" + + return seq_name + + def autoconnect_qualified(self, info): + if RNS.Reticulum.should_autoconnect_unverified_implementations(): return True + if not "impl_name" in info: return False + if not info["impl_name"] in self.AUTOCONNECT_IMPLS: return False + if not "version" in info or not info["version"]: return False + + version = version_tuple(info["version"]) + if version == None: return False + return version >= version_tuple(self.AUTOCONNECT_MIN_V) + def autoconnect(self, info): try: if RNS.Reticulum.should_autoconnect_discovered_interfaces(): @@ -720,17 +796,16 @@ class InterfaceDiscovery(): if autoconnected_count < RNS.Reticulum.max_autoconnected_interfaces(): interface_type = info["type"] if interface_type in self.AUTOCONNECT_TYPES: + if not self.autoconnect_qualified(info): + impl = f"{info['impl_name']} {info['version']}" if ("impl_name" in info and "version" in info and info["impl_name"] and info["version"]) else "unknown implementation" + RNS.log(f"Not auto-connecting discovered {interface_type} {info['name']} ({impl}), auto-connect criteria not satisfied", RNS.LOG_DEBUG) + return + endpoint_hash = self.endpoint_hash(info) exists = self.interface_exists(info) if exists: RNS.log(f"Discovered {interface_type} already exists, not auto-connecting", RNS.LOG_DEBUG) else: - if interface_type == "TCPClientInterface": - RNS.log(f"Your operating system does not support the Backbone interface type, and must degrade to using TCPClientInterface instead", RNS.LOG_WARNING) - RNS.log(f"Auto-connecting discovered TCPClient interfaces is not yet implemented, aborting auto-connect", RNS.LOG_WARNING) - RNS.log(f"You can obtain the configuration entry and add this interface manually instead using rnstatus -D", RNS.LOG_WARNING) - return - if interface_type == "I2PInterface": RNS.log(f"Auto-connecting discovered I2P interfaces is not yet implemented, aborting auto-connect", RNS.LOG_DEBUG) RNS.log(f"You can obtain the configuration entry and add this interface manually instead using rnstatus -D", RNS.LOG_DEBUG) @@ -748,35 +823,57 @@ class InterfaceDiscovery(): RNS.log(f"Not auto-connecting discovered interface with invalid IP address: {info['reachable_on']}", RNS.LOG_DEBUG) return - interface_name = info["name"] - config_entry = info["config_entry"] - interface_config = {} - interface_config["name"] = f"{interface_name}" - ifac_netname = info["ifac_netname"] if "ifac_netname" in info else None - ifac_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None - interface = None + with self.autoconnect_lock: + if self.interface_exists(info): return + backbone_support = (not RNS.vendor.platformutils.is_windows() and not RNS.vendor.platformutils.is_darwin()) - if interface_type == "BackboneInterface": - from RNS.Interfaces import BackboneInterface - interface_config["target_host"] = info["reachable_on"] - interface_config["target_port"] = info["port"] - interface = BackboneInterface.BackboneClientInterface(RNS.Transport, interface_config) + interface_name = self.autoconnect_interface_name(info["name"]) + if interface_name != info["name"]: + RNS.log(f"Auto-connect name collision for \"{info['name']}\", connecting as \"{interface_name}\"", RNS.LOG_NOTICE) - if interface: - RNS.log(f"Auto-connecting discovered {interface_type} {interface_name}") - interface.autoconnect_hash = endpoint_hash - interface.autoconnect_source = info["network_id"] - if RNS.Reticulum.autoconnect_interface_mode(): mode = RNS.Reticulum.autoconnect_interface_mode() - else: mode = self.AC_TRANSPORT_MODE if RNS.Reticulum.transport_enabled() else None - internal_a = True if RNS.Reticulum.autoconnect_announces_to_internal() else None - gravity = RNS.Reticulum.autoconnect_interface_gravity() or self.AC_GRAVITY - ar_target = RNS.Reticulum.get_instance()._default_ar_target() if RNS.Reticulum.transport_enabled() else None - ar_penalty = RNS.Reticulum.get_instance()._default_ar_penalty() if RNS.Reticulum.transport_enabled() else None - ar_grace = RNS.Reticulum.get_instance()._default_ar_grace() if RNS.Reticulum.transport_enabled() else None - RNS.Reticulum.get_instance()._add_interface(interface, mode=mode, ifac_netname=ifac_netname, ifac_netkey=ifac_netkey, configured_bitrate=5E6, - announce_rate_target=ar_target, announce_rate_grace=ar_grace, announce_rate_penalty=ar_penalty, - announces_to_internal=internal_a, gravity=gravity) - self.monitor_interface(interface) + config_entry = info["config_entry"] + interface_config = {} + interface_config["name"] = f"{interface_name}" + + # TODO: Temporary measure to sanitize invalidly persisted "None" values + # for incorrect IFAC parameters published due to unguarded nonsensical + # node-side configuration. Potentially remove once nodes upgrade to RNS + # versions that guard against the configuration mismatch. + if "ifac_netname" in info and info["ifac_netname"] == "None": info["ifac_netname"] = None + if "ifac_netkey" in info and info["ifac_netkey"] == "None": info["ifac_netkey"] = None + + ifac_netname = info["ifac_netname"] if "ifac_netname" in info and info["ifac_netname"] else None + ifac_netkey = info["ifac_netkey"] if "ifac_netkey" in info and info["ifac_netkey"] else None + interface = None + + if interface_type == "BackboneInterface": + if backbone_support: + from RNS.Interfaces import BackboneInterface + interface_class = BackboneInterface.BackboneClientInterface + else: + from RNS.Interfaces import TCPInterface + interface_class = TCPInterface.TCPClientInterface + RNS.log(f"BackboneInterface is not yet supported on this operating system, auto-connecting discovered {interface_type} {interface_name} using TCPClientInterface", RNS.LOG_NOTICE) + + interface_config["target_host"] = info["reachable_on"] + interface_config["target_port"] = info["port"] + interface = interface_class(RNS.Transport, interface_config) + + if interface: + RNS.log(f"Auto-connecting discovered {interface_type} {interface_name}") + interface.autoconnect_hash = endpoint_hash + interface.autoconnect_source = info["network_id"] + if RNS.Reticulum.autoconnect_interface_mode(): mode = RNS.Reticulum.autoconnect_interface_mode() + else: mode = self.AC_TRANSPORT_MODE if RNS.Reticulum.transport_enabled() else None + internal_a = True if RNS.Reticulum.autoconnect_announces_to_internal() else None + gravity = RNS.Reticulum.autoconnect_interface_gravity() or self.AC_GRAVITY + ar_target = RNS.Reticulum.get_instance()._default_ar_target() if RNS.Reticulum.transport_enabled() else None + ar_penalty = RNS.Reticulum.get_instance()._default_ar_penalty() if RNS.Reticulum.transport_enabled() else None + ar_grace = RNS.Reticulum.get_instance()._default_ar_grace() if RNS.Reticulum.transport_enabled() else None + RNS.Reticulum.get_instance()._add_interface(interface, mode=mode, ifac_netname=ifac_netname, ifac_netkey=ifac_netkey, configured_bitrate=5E6, + announce_rate_target=ar_target, announce_rate_grace=ar_grace, announce_rate_penalty=ar_penalty, + announces_to_internal=internal_a, gravity=gravity) + self.monitor_interface(interface) except Exception as e: RNS.log(f"Error while auto-connecting discovered interface: {e}", RNS.LOG_ERROR) @@ -895,6 +992,18 @@ def is_hostname(hostname): allowed = re.compile(r"(?!-)[a-z0-9-]{1,63}(?= BackboneInterface.DP_EC_DEAD_TIME: - RNS.log(f"No egress control drain progress for {RNS.prettyshorttime(BackboneInterface.DP_EC_DEAD_TIME, compact=True)} on {interface}, tearing down", RNS.LOG_WARNING) + RNS.log(f"No egress control drain progress for {RNS.prettyshorttime(BackboneInterface.DP_EC_DEAD_TIME, compact=True)} on {interface}, tearing down", RNS.LOG_NOTICE) try: if hasattr(interface, "socket") and interface.socket: fileno = interface.socket.fileno() @@ -482,6 +482,7 @@ class BackboneInterface(Interface): for interface in interfaces: if interface.detached: continue + if isinstance(interface, RNS.Interfaces.LocalInterface.LocalClientInterface): continue BackboneInterface._dp_ec_evaluate(interface, now) except Exception as e: @@ -508,7 +509,7 @@ class BackboneInterface(Interface): interfaces = list(BackboneInterface.spawned_interface_filenos.values()) if q_depth > BackboneInterface.DP_IC_MID_WM: - producers = [iface for iface in interfaces if iface.dp_ingress_packets > 0] + producers = [iface for iface in interfaces if iface.dp_ingress_packets > 0 and not isinstance(iface, RNS.Interfaces.LocalInterface.LocalClientInterface)] if producers: producers.sort(key=lambda p: p.dp_ingress_packets, reverse=True) selected = producers[0] @@ -737,6 +738,10 @@ class BackboneInterface(Interface): spawned_interface.announce_rate_penalty = self.announce_rate_penalty spawned_interface.mode = self.mode spawned_interface.gravity = self.gravity + spawned_interface.recursive_prs = self.recursive_prs + spawned_interface.announces_from_internal = self.announces_from_internal + spawned_interface.announces_to_internal = self.announces_to_internal + spawned_interface.announce_cap = self.announce_cap spawned_interface.HW_MTU = self.HW_MTU RNS.log("Spawned new BackboneClient Interface: "+str(spawned_interface), RNS.LOG_PATHING) if RNS.sl(RNS.LOG_PATHING) else None RNS.Transport.add_interface(spawned_interface) @@ -925,11 +930,10 @@ class BackboneClientInterface(Interface): def detach(self): self.online = False + self.detached = True if self.socket != None: if hasattr(self.socket, "close"): if callable(self.socket.close): - self.detached = True - try: if self.socket != None: self.socket.shutdown(socket.SHUT_RDWR) except Exception as e: @@ -1030,7 +1034,7 @@ class BackboneClientInterface(Interface): def process_outgoing(self, data): if self.online and not self.detached: try: - frame = bytes([HDLC.FLAG])+HDLC.escape(data)+bytes([HDLC.FLAG]) + frame = HDLC.frame(data) if self.tx_stalled or not self.transmit_buffer.append(frame, self.tx_hwm): self.tx_drops += 1 self.tx_dropped_bytes += len(frame) diff --git a/RNS/Interfaces/I2PInterface.py b/RNS/Interfaces/I2PInterface.py index f8a562c6..0561829d 100644 --- a/RNS/Interfaces/I2PInterface.py +++ b/RNS/Interfaces/I2PInterface.py @@ -537,6 +537,7 @@ class I2PInterfacePeer(Interface): raise IOError("Attempt to reconnect on a non-initiator I2P interface") def process_incoming(self, data): + if not data: return self.rxb += len(data) if hasattr(self, "parent_interface") and self.parent_interface != None and self.parent_count: self.parent_interface.rxb += len(data) diff --git a/RNS/Interfaces/Interface.py b/RNS/Interfaces/Interface.py index 2c529d41..619f32da 100755 --- a/RNS/Interfaces/Interface.py +++ b/RNS/Interfaces/Interface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -114,6 +114,7 @@ class Interface: self.HW_MTU = None self.__hash = None + self.announce_cap = RNS.Reticulum.ANNOUNCE_CAP/100.0 self.supports_discovery = False self.discoverable = False self.last_discovery_announce = 0 @@ -389,7 +390,7 @@ class Interface: def process_announce_queue(self): if not hasattr(self, "announce_cap"): - self.announce_cap = RNS.Reticulum.ANNOUNCE_CAP + self.announce_cap = RNS.Reticulum.ANNOUNCE_CAP/100.0 if hasattr(self, "announce_queue"): try: @@ -436,6 +437,9 @@ class Interface: def detach(self): pass + def teardown(self): + pass + @staticmethod def get_config_obj(config_in): if type(config_in) == ConfigObj: return config_in diff --git a/RNS/Interfaces/KISSInterface.py b/RNS/Interfaces/KISSInterface.py index 036904e4..9323ea6f 100644 --- a/RNS/Interfaces/KISSInterface.py +++ b/RNS/Interfaces/KISSInterface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -124,6 +124,7 @@ class KISSInterface(Interface): self.flow_control = flow_control self.shared_medium = True self.interface_ready = False + self.reconnecting = False self.flow_control_timeout = 5 self.flow_control_locked = time.time() @@ -140,15 +141,17 @@ class KISSInterface(Interface): try: self.open_port() + if self.serial.is_open: self.configure_device() + else: raise IOError("Could not open serial port") + except Exception as e: - RNS.log("Could not open serial port "+self.port, RNS.LOG_ERROR) - raise e - - if self.serial.is_open: - self.configure_device() - else: - raise IOError("Could not open serial port") - + RNS.log(f"Could not open serial port for {self}", RNS.LOG_ERROR) + RNS.log(f"The contained exception was: {e}", RNS.LOG_ERROR) + RNS.log(f"Reticulum will attempt to bring up this interface periodically", RNS.LOG_ERROR) + if not self.detached and not self.reconnecting: + thread = threading.Thread(target=self.reconnect_port) + thread.daemon = True + thread.start() def open_port(self): RNS.log("Opening serial port "+self.port+"...", RNS.LOG_VERBOSE) @@ -166,6 +169,11 @@ class KISSInterface(Interface): dsrdtr = False, ) + def detach(self): + self.detached = True + self.online = False + try: self.serial.close() + except Exception as e: RNS.log(f"Could not close port for {self} at detach: {e}", RNS.LOG_ERROR) def configure_device(self): # Allow time for interface to initialise before config @@ -246,6 +254,7 @@ class KISSInterface(Interface): def process_incoming(self, data): + if not data: return self.rxb += len(data) self.owner.inbound(data, self) @@ -360,30 +369,28 @@ class KISSInterface(Interface): RNS.log("A serial port error occurred, the contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is now offline.", RNS.LOG_ERROR) - if RNS.Reticulum.panic_on_interface_error: - RNS.panic() + if RNS.Reticulum.panic_on_interface_error: RNS.panic() RNS.log("Reticulum will attempt to reconnect the interface periodically.", RNS.LOG_ERROR) self.online = False - self.serial.close() - self.reconnect_port() + try: self.serial.close() + except Exception as e: RNS.log(f"Could not close port for {self}", RNS.LOG_ERROR) + if not self.detached and not self.reconnecting: self.reconnect_port() def reconnect_port(self): - while not self.online: + self.reconnecting = True + while not self.online and not self.detached: try: time.sleep(5) RNS.log("Attempting to reconnect serial port "+str(self.port)+" for "+str(self)+"...", RNS.LOG_VERBOSE) self.open_port() - if self.serial.is_open: - self.configure_device() - except Exception as e: - RNS.log("Error while reconnecting port, the contained exception was: "+str(e), RNS.LOG_ERROR) + if self.serial.is_open: self.configure_device() + except Exception as e: RNS.log("Error while reconnecting port, the contained exception was: "+str(e), RNS.LOG_ERROR) - RNS.log("Reconnected serial port for "+str(self)) + self.reconnecting = False + if self.online: RNS.log("Reconnected serial port for "+str(self)) - def should_ingress_limit(self): - return False + def should_ingress_limit(self): return False - def __str__(self): - return "KISSInterface["+self.name+"]" \ No newline at end of file + def __str__(self): return "KISSInterface["+self.name+"]" \ No newline at end of file diff --git a/RNS/Interfaces/LocalInterface.py b/RNS/Interfaces/LocalInterface.py index 18957d7d..bef1c3a2 100644 --- a/RNS/Interfaces/LocalInterface.py +++ b/RNS/Interfaces/LocalInterface.py @@ -58,10 +58,12 @@ class LocalClientInterface(Interface): def __init__(self, owner, name, target_port = None, connected_socket=None, socket_path=None): super().__init__() - self.epoll_backend = False - self.HW_MTU = 262144 - self.online = False - self.ifac_size = self.DEFAULT_IFAC_SIZE + self.owner = owner + self.bitrate = 1_000_000_000 + self.epoll_backend = False + self.HW_MTU = 262144 + self.online = False + self.ifac_size = self.DEFAULT_IFAC_SIZE if socket_path != None and RNS.Reticulum.get_instance().use_af_unix: self.socket_path = f"\0rns/{socket_path}" else: self.socket_path = None @@ -110,8 +112,6 @@ class LocalClientInterface(Interface): self.target_port = target_port self.connect() - self.owner = owner - self.bitrate = 1_000_000_000 self.online = True self.writing = False @@ -218,7 +218,7 @@ class LocalClientInterface(Interface): if self.online: try: if self.epoll_backend: - frame = bytes([HDLC.FLAG])+HDLC.escape(data)+bytes([HDLC.FLAG]) + frame = HDLC.frame(data) if self.tx_stalled or not self.transmit_buffer.append(frame, self.tx_hwm): self.tx_drops += 1 self.tx_dropped_bytes += len(frame) @@ -235,7 +235,7 @@ class LocalClientInterface(Interface): s = len(data) / self.bitrate * 8 time.sleep(s) - data = bytes([HDLC.FLAG])+HDLC.escape(data)+bytes([HDLC.FLAG]) + data = HDLC.frame(data) self.socket.sendall(data) self.writing = False self.txb += len(data) diff --git a/RNS/Interfaces/PipeInterface.py b/RNS/Interfaces/PipeInterface.py index 6b420aa5..eca88b5c 100644 --- a/RNS/Interfaces/PipeInterface.py +++ b/RNS/Interfaces/PipeInterface.py @@ -120,6 +120,7 @@ class PipeInterface(Interface): def process_incoming(self, data): + if not data: return self.rxb += len(data) self.owner.inbound(data, self) diff --git a/RNS/Interfaces/RNodeInterface.py b/RNS/Interfaces/RNodeInterface.py index 42524bff..bf623672 100644 --- a/RNS/Interfaces/RNodeInterface.py +++ b/RNS/Interfaces/RNodeInterface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -386,6 +386,7 @@ class RNodeInterface(Interface): RNS.log(f"Opening BLE connection for {self}...") self.timeout = 1250 if self.ble != None and self.ble.running == False: + RNS.log(f"Cleaning up previous BLE connection for {self}...") self.ble.close() self.ble.cleanup() self.ble = None @@ -442,7 +443,11 @@ class RNodeInterface(Interface): ble_detect_timeout = 5.0 detect_time = time.time() while not self.detected and time.time() < detect_time + ble_detect_timeout: time.sleep(0.1) - if not self.detected: RNS.log(f"RNode detect timed out over BLE", RNS.LOG_ERROR) + if not self.detected: + RNS.log(f"RNode detect timed out over BLE", RNS.LOG_ERROR) + if self.ble: + self.ble.should_run = False + self.ble.must_disconnect = True else: sleep(0.2) @@ -480,8 +485,7 @@ class RNodeInterface(Interface): self.setLTALock() self.setRadioState(KISS.RADIO_STATE_ON) - if self.use_ble: - time.sleep(2) + if self.use_ble: time.sleep(2) def detect(self): kiss_command = bytes([KISS.FEND, KISS.CMD_DETECT, KISS.DETECT_REQ, KISS.FEND, KISS.CMD_FW_VERSION, 0x00, KISS.FEND, KISS.CMD_PLATFORM, 0x00, KISS.FEND, KISS.CMD_MCU, 0x00, KISS.FEND]) @@ -687,10 +691,8 @@ class RNodeInterface(Interface): RNS.log("Radio state mismatch", RNS.LOG_ERROR) self.validcfg = False - if (self.validcfg): - return True - else: - return False + if (self.validcfg): return True + else: return False def updateBitrate(self): @@ -702,6 +704,7 @@ class RNodeInterface(Interface): self.bitrate = 0 def process_incoming(self, data): + if not data: return self.rxb += len(data) self.owner.inbound(data, self) @@ -1154,19 +1157,17 @@ class RNodeInterface(Interface): except Exception as e: self.online = False - RNS.log("A serial port error occurred, the contained exception was: "+str(e), RNS.LOG_ERROR) - RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is now offline.", RNS.LOG_ERROR) + if not self.detached: + RNS.log("A serial port error occurred, the contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is now offline.", RNS.LOG_ERROR) - if RNS.Reticulum.panic_on_interface_error: - RNS.panic() + if RNS.Reticulum.panic_on_interface_error: RNS.panic() - RNS.log("Reticulum will attempt to reconnect the interface periodically.", RNS.LOG_ERROR) + RNS.log("Reticulum will attempt to reconnect the interface periodically.", RNS.LOG_ERROR) self.online = False - try: - self.serial.close() - except Exception as e: - pass + try: self.serial.close() + except Exception as e: pass if not self.detached and not self.reconnecting: self.reconnect_port() @@ -1192,14 +1193,20 @@ class RNodeInterface(Interface): self.disable_external_framebuffer() self.setRadioState(KISS.RADIO_STATE_OFF) self.leave() + self.serial.close() except Exception as e: RNS.log(f"An error occurred while detaching {self}: {e}", RNS.LOG_ERROR) - if self.use_ble: self.ble.close() - if self.use_tcp: + if self.use_ble: + self.ble.close() + self.ble.cleanup() + self.ble = None + elif self.use_tcp: time.sleep(0.5) self.tcp.close() + else: + self.serial.close() def should_ingress_limit(self): return False @@ -1297,6 +1304,7 @@ class BLEConnection(): self.must_disconnect = False self.connect_job_running = False self.device_disappeared = False + self._windows_paired_addrs = None import importlib.util if BLEConnection.bleak == None: @@ -1307,8 +1315,8 @@ class BLEConnection(): import asyncio BLEConnection.asyncio = asyncio else: - RNS.log("Using the RNode interface over BLE requires a the \"bleak\" module to be installed.", RNS.LOG_CRITICAL) - RNS.log("You can install one with the command: python3 -m pip install bleak", RNS.LOG_CRITICAL) + RNS.log("Using the RNode interface over BLE requires the \"bleak\" module to be installed.", RNS.LOG_CRITICAL) + RNS.log("You can install it with the command: python3 -m pip install bleak", RNS.LOG_CRITICAL) RNS.panic() self.should_run = True @@ -1324,6 +1332,7 @@ class BLEConnection(): self.should_run = False def connection_job(self): + self.running = True while self.should_run: if self.ble_device == None: self.ble_device = self.find_target_device() @@ -1350,6 +1359,7 @@ class BLEConnection(): self.owner.ble_receive(data) self.connected = True + self.device_disappeared = False self.ble_device = ble_client self.last_client = ble_client self.owner.port = str(f"ble://{ble_client.address}") @@ -1384,6 +1394,8 @@ class BLEConnection(): def find_target_device(self): RNS.log(f"Searching for attachable BLE device for {self.owner}...", RNS.LOG_EXTREME) + if RNS.vendor.platformutils.is_windows(): + self._windows_paired_addrs = self._get_windows_paired_ble_addresses() def device_filter(device: self.bleak.backends.device.BLEDevice, adv: self.bleak.backends.scanner.AdvertisementData): if BLEConnection.UART_SERVICE_UUID.lower() in adv.service_uuids: if self.device_bonded(device): @@ -1415,6 +1427,9 @@ class BLEConnection(): def device_bonded(self, device): try: + if self._windows_paired_addrs is not None: + return device.address is not None and device.address.lower() in self._windows_paired_addrs + if hasattr(device, "details"): if "props" in device.details and "Bonded" in device.details["props"]: if device.details["props"]["Bonded"] == True: @@ -1425,6 +1440,15 @@ class BLEConnection(): return False + def _get_windows_paired_ble_addresses(self): + from winrt.windows.devices.bluetooth import BluetoothLEDevice + from winrt.windows.devices.enumeration import DeviceInformation + async def _query(): + selector = BluetoothLEDevice.get_device_selector_from_pairing_state(True) + infos = await DeviceInformation.find_all_async_aqs_filter(selector) + return set(info.id.split("-")[-1].lower() for info in infos) + return self.asyncio.run(_query()) + class TCPConnection(): TARGET_PORT = 7633 CONNECT_TIMEOUT = 5.0 diff --git a/RNS/Interfaces/RNodeMultiInterface.py b/RNS/Interfaces/RNodeMultiInterface.py index 97b74abd..6e0f5fc9 100644 --- a/RNS/Interfaces/RNodeMultiInterface.py +++ b/RNS/Interfaces/RNodeMultiInterface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -916,6 +916,7 @@ class RNodeMultiInterface(Interface): if interface != 0: self.setRadioState(KISS.RADIO_STATE_OFF, interface) self.leave() + self.serial.close() def teardown_subinterfaces(self): for interface in self.subinterfaces: @@ -1128,6 +1129,7 @@ class RNodeSubInterface(Interface): self.bitrate = 0 def process_incoming(self, data): + if not data: return self.rxb += len(data) self.owner.inbound(data, self) diff --git a/RNS/Interfaces/SerialInterface.py b/RNS/Interfaces/SerialInterface.py index 0bce146f..0e8d7665 100755 --- a/RNS/Interfaces/SerialInterface.py +++ b/RNS/Interfaces/SerialInterface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -97,6 +97,7 @@ class SerialInterface(Interface): self.timeout = 100 self.online = False self.bitrate = self.speed + self.reconnecting = False if parity.lower() == "e" or parity.lower() == "even": self.parity = serial.PARITY_EVEN @@ -106,15 +107,17 @@ class SerialInterface(Interface): try: self.open_port() + if self.serial.is_open: self.configure_device() + else: raise IOError("Could not open serial port") + except Exception as e: - RNS.log("Could not open serial port for interface "+str(self), RNS.LOG_ERROR) - raise e - - if self.serial.is_open: - self.configure_device() - else: - raise IOError("Could not open serial port") - + RNS.log(f"Could not open serial port for {self}", RNS.LOG_ERROR) + RNS.log(f"The contained exception was: {e}", RNS.LOG_ERROR) + RNS.log(f"Reticulum will attempt to bring up this interface periodically", RNS.LOG_ERROR) + if not self.detached and not self.reconnecting: + thread = threading.Thread(target=self.reconnect_port) + thread.daemon = True + thread.start() def open_port(self): RNS.log("Opening serial port "+self.port+"...", RNS.LOG_VERBOSE) @@ -132,6 +135,11 @@ class SerialInterface(Interface): dsrdtr = False, ) + def detach(self): + self.detached = True + self.online = False + try: self.serial.close() + except Exception as e: RNS.log(f"Could not close port for {self} at detach: {e}", RNS.LOG_ERROR) def configure_device(self): sleep(0.5) @@ -141,12 +149,11 @@ class SerialInterface(Interface): self.online = True RNS.log("Serial port "+self.port+" is now open", RNS.LOG_VERBOSE) - def process_incoming(self, data): + if not data: return self.rxb += len(data) self.owner.inbound(data, self) - def process_outgoing(self,data): if self.online: data = bytes([HDLC.FLAG])+HDLC.escape(data)+bytes([HDLC.FLAG]) @@ -155,7 +162,6 @@ class SerialInterface(Interface): if written != len(data): raise IOError("Serial interface only wrote "+str(written)+" bytes of "+str(len(data))) - def readLoop(self): try: in_frame = False @@ -199,30 +205,28 @@ class SerialInterface(Interface): RNS.log("A serial port error occurred, the contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is now offline.", RNS.LOG_ERROR) - if RNS.Reticulum.panic_on_interface_error: - RNS.panic() + if RNS.Reticulum.panic_on_interface_error: RNS.panic() RNS.log("Reticulum will attempt to reconnect the interface periodically.", RNS.LOG_ERROR) self.online = False - self.serial.close() - self.reconnect_port() + try: self.serial.close() + except Exception as e: RNS.log(f"Could not close port for {self}", RNS.LOG_ERROR) + if not self.detached and not self.reconnecting: self.reconnect_port() def reconnect_port(self): - while not self.online: + self.reconnecting = True + while not self.online and not self.detached: try: time.sleep(5) RNS.log("Attempting to reconnect serial port "+str(self.port)+" for "+str(self)+"...", RNS.LOG_VERBOSE) self.open_port() - if self.serial.is_open: - self.configure_device() - except Exception as e: - RNS.log("Error while reconnecting port, the contained exception was: "+str(e), RNS.LOG_ERROR) + if self.serial.is_open: self.configure_device() + except Exception as e: RNS.log("Error while reconnecting port, the contained exception was: "+str(e), RNS.LOG_ERROR) - RNS.log("Reconnected serial port for "+str(self)) + self.reconnecting = False + if self.online: RNS.log("Reconnected serial port for "+str(self)) - def should_ingress_limit(self): - return False + def should_ingress_limit(self): return False - def __str__(self): - return "SerialInterface["+self.name+"]" + def __str__(self): return "SerialInterface["+self.name+"]" diff --git a/RNS/Interfaces/TCPInterface.py b/RNS/Interfaces/TCPInterface.py index c0b66ba1..12d25c86 100644 --- a/RNS/Interfaces/TCPInterface.py +++ b/RNS/Interfaces/TCPInterface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -208,6 +208,7 @@ class TCPClientInterface(Interface): def detach(self): self.online = False + self.detached = True if self.socket != None: if hasattr(self.socket, "close"): if callable(self.socket.close): @@ -272,7 +273,7 @@ class TCPClientInterface(Interface): if not self.reconnecting: self.reconnecting = True attempts = 0 - while not self.online: + while not self.online and not self.detached: time.sleep(TCPClientInterface.RECONNECT_WAIT) attempts += 1 @@ -302,6 +303,7 @@ class TCPClientInterface(Interface): raise IOError("Attempt to reconnect on a non-initiator TCP interface") def process_incoming(self, data): + if not data: return if self.online and not self.detached: self.rxb += len(data) if hasattr(self, "parent_interface") and self.parent_interface != None: @@ -426,7 +428,7 @@ class TCPClientInterface(Interface): self.online = False RNS.log("An interface error occurred for "+str(self)+", the contained exception was: "+str(e), RNS.LOG_WARNING) - if self.initiator: + if self.initiator and not self.detached: RNS.log("Attempting to reconnect...", RNS.LOG_WARNING) self.reconnect() else: @@ -452,12 +454,9 @@ class TCPClientInterface(Interface): if not self.initiator: RNS.Transport.remove_interface(self) - def __str__(self): - if ":" in self.target_ip: - ip_str = f"[{self.target_ip}]" - else: - ip_str = f"{self.target_ip}" + if ":" in self.target_ip: ip_str = f"[{self.target_ip}]" + else: ip_str = f"{self.target_ip}" return "TCPInterface["+str(self.name)+"/"+ip_str+":"+str(self.target_port)+"]" @@ -637,6 +636,10 @@ class TCPServerInterface(Interface): spawned_interface.announce_rate_penalty = self.announce_rate_penalty spawned_interface.mode = self.mode spawned_interface.gravity = self.gravity + spawned_interface.recursive_prs = self.recursive_prs + spawned_interface.announces_from_internal = self.announces_from_internal + spawned_interface.announces_to_internal = self.announces_to_internal + spawned_interface.announce_cap = self.announce_cap spawned_interface.HW_MTU = self.HW_MTU spawned_interface.online = True RNS.log("Spawned new TCPClient Interface: "+str(spawned_interface), RNS.LOG_VERBOSE) @@ -686,10 +689,8 @@ class TCPServerInterface(Interface): def __str__(self): - if ":" in self.bind_ip: - ip_str = f"[{self.bind_ip}]" - else: - ip_str = f"{self.bind_ip}" + if ":" in self.bind_ip: ip_str = f"[{self.bind_ip}]" + else: ip_str = f"{self.bind_ip}" return "TCPServerInterface["+self.name+"/"+ip_str+":"+str(self.bind_port)+"]" diff --git a/RNS/Interfaces/UDPInterface.py b/RNS/Interfaces/UDPInterface.py index 8dd9c78e..e2baecac 100644 --- a/RNS/Interfaces/UDPInterface.py +++ b/RNS/Interfaces/UDPInterface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -113,8 +113,17 @@ class UDPInterface(Interface): self.forward_ip = forwardip self.forward_port = forwardport + def detach(self): + self.detached = True + self.online = False + if self.server: + try: + self.server.server_close() + self.server.shutdown() + except Exception as e: RNS.log(f"Could not shut down UDP listener for {self}: {e}", RNS.LOG_ERROR) def process_incoming(self, data): + if not data: return self.rxb += len(data) self.owner.inbound(data, self) diff --git a/RNS/Interfaces/util/HDLC.py b/RNS/Interfaces/util/HDLC.py index ab0f1735..bd7fd976 100644 --- a/RNS/Interfaces/util/HDLC.py +++ b/RNS/Interfaces/util/HDLC.py @@ -50,6 +50,15 @@ class HDLC(): frame = frame.replace(HDLC.ESCPD_ESC, HDLC.ESC_B) return frame + @staticmethod + def frame(data): + esc = HDLC.escape(data) + frame = bytearray(len(esc)+2) + frame[0] = HDLC.FLAG + frame[1:-1] = esc + frame[-1] = HDLC.FLAG + return frame + class ReceiveBuffer(): def __init__(self, mtu, min_frame_len, max_frame_len=None, on_frame=None, on_invalid=None): self._mtu = mtu diff --git a/RNS/Link.py b/RNS/Link.py index df7997f5..8d5079da 100644 --- a/RNS/Link.py +++ b/RNS/Link.py @@ -593,7 +593,7 @@ class Link: def get_expected_rate(self): """ - :returns: The packet expected in-flight data rate of an established link. + :returns: The expected in-flight data rate of an established link. """ if self.status == Link.ACTIVE: return self.expected_rate else: return None @@ -1395,7 +1395,7 @@ class RequestReceipt(): time.sleep(0.1) def request_timed_out(self, packet_receipt): - if self in self.link.pending_requests and self.status == RequestReceipt.DELIVERED: + if self in self.link.pending_requests and self.status in [RequestReceipt.DELIVERED, RequestReceipt.SENT]: self.status = RequestReceipt.FAILED self.concluded_at = time.time() self.link.pending_requests.remove(self) @@ -1405,7 +1405,7 @@ class RequestReceipt(): except Exception as e: RNS.log("Error while executing request timed out callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR) def response_rejected(self): - if self in self.link.pending_requests and self.status == RequestReceipt.DELIVERED: + if self in self.link.pending_requests and self.status in [RequestReceipt.DELIVERED, RequestReceipt.SENT]: self.status = RequestReceipt.FAILED self.concluded_at = time.time() self.link.pending_requests.remove(self) diff --git a/RNS/Packet.py b/RNS/Packet.py index 74712b77..991819bc 100755 --- a/RNS/Packet.py +++ b/RNS/Packet.py @@ -305,7 +305,9 @@ class Packet: if RNS.Transport.outbound(self): return self.receipt else: - RNS.log(f"No interfaces could process the outbound {self.hops} hop, type {self.packet_type} packet for {self.destination}", RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None + if not self.attached_interface: + RNS.log(f"No interfaces could process the outbound {self.hops} hop, type {self.packet_type} packet for {self.destination}", RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None + self.sent = False self.receipt = None return False diff --git a/RNS/Resource.py b/RNS/Resource.py index 5faf0dbf..c7466af6 100644 --- a/RNS/Resource.py +++ b/RNS/Resource.py @@ -30,6 +30,7 @@ import RNS import os +import io import bz2 import math import time @@ -280,15 +281,18 @@ class Resource: if hasattr(data, "read"): if data_size == None: data_size = os.stat(data.name).st_size - if data_size == 0: - RNS.log(f"Zero-sized stat at resource init, probably stream. Attempting to proxy stream data...", RNS.LOG_DEBUG) - stream_proxy = tempfile.TemporaryFile() - stream_proxy.write(data.read()) - data_size = os.stat(stream_proxy.name).st_size - if data_size: RNS.log(f"Stream proxy succeeded, final data size is {RNS.prettysize(data_size)}", RNS.LOG_DEBUG) - else: RNS.log(f"Resource initialisation received an invalid readable input, or stream data that could not be proxied, the transfer will likely fail.", RNS.LOG_WARNING) - data = stream_proxy + if isinstance(data, io.BufferedReader): + RNS.log(f"Attempting to proxy stream data...", RNS.LOG_DEBUG) + stream_proxy = tempfile.TemporaryFile() + stream_proxy.write(data.read()) + stream_proxy.flush(); stream_proxy.seek(0) + data_size = os.stat(stream_proxy.name).st_size + if data_size: RNS.log(f"Stream proxy succeeded, final data size is {RNS.prettysize(data_size)}", RNS.LOG_DEBUG) + else: RNS.log(f"Resource initialisation received an invalid readable input, or stream data that could not be proxied, the transfer will likely fail.", RNS.LOG_WARNING) + data = stream_proxy + + else: RNS.log(f"Got zero-sized readable at resource initialisation, the transfer will likely.", RNS.LOG_WARNING) self.total_size = data_size + self.metadata_size diff --git a/RNS/Reticulum.py b/RNS/Reticulum.py index 77b742f5..7b11a351 100755 --- a/RNS/Reticulum.py +++ b/RNS/Reticulum.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -257,11 +257,13 @@ class Reticulum: Reticulum.__local_hops_delta = False Reticulum.__link_mtu_discovery = Reticulum.LINK_MTU_DISCOVERY Reticulum.__remote_management_enabled = False + Reticulum.__interface_management_enabled = True Reticulum.__use_implicit_proof = True Reticulum.__allow_probes = False Reticulum.__discovery_enabled = False Reticulum.__discover_interfaces = False Reticulum.__autoconnect_discovered_interfaces = False + Reticulum.__autoconnect_unverified = False Reticulum.__autoconnect_interface_mode = None Reticulum.__autoconnect_interface_gravity = None Reticulum.__autoconnect_announces_to_internal = None @@ -548,6 +550,11 @@ class Reticulum: v = self.config["reticulum"].as_bool(option) if v == True: Reticulum.__remote_management_enabled = True + if option == "enable_interface_management": + v = self.config["reticulum"].as_bool(option) + if v == False: Reticulum.__interface_management_enabled = False + else: Reticulum.__interface_management_enabled = True + if option == "remote_management_allowed": v = self.config["reticulum"].as_list(option) for hexhash in v: @@ -622,6 +629,10 @@ class Reticulum: v = self.config["reticulum"].as_int(option) if v > 0: Reticulum.__autoconnect_discovered_interfaces = v + if option == "autoconnect_unverified_implementations": + v = self.config["reticulum"].as_bool(option) + Reticulum.__autoconnect_unverified = v + if option == "autoconnect_interface_mode": v = None; dmode = str(self.config["reticulum"]["autoconnect_interface_mode"]).lower() if dmode == "full": v = Interface.Interface.MODE_FULL @@ -757,7 +768,79 @@ class Reticulum: RNS.log("System interfaces are ready", RNS.LOG_VERBOSE) - def _synthesize_interface(self, config, name, instance_init=False): + def _attach_interface(self, name, internal_forced=False): + if not internal_forced and not Reticulum.__interface_management_enabled: return False + try: + interfaces = { iface.name: iface for iface in RNS.Transport.interfaces } + if name in interfaces: + RNS.log(f"Attempt to attach existing interface \"{name}\"", RNS.LOG_WARNING) + return False + + else: + try: config = ConfigObj(self.configpath) + except Exception as e: + RNS.log(f"Could not parse the configuration at {self.configpath} during interface attach", RNS.LOG_ERROR) + return None + + if "interfaces" in config: + if not name in config["interfaces"]: + RNS.log(f"Cannot attach interface \"{name}\", no configuration entry exists", RNS.LOG_ERROR) + return None + + else: + interface_config = config["interfaces"][name] + self._synthesize_interface(interface_config, name, force_attach=True) + RNS.log(f"Interface \"{name}\" was attached", RNS.LOG_NOTICE) + return True + + except Exception as e: RNS.log(f"Error while detaching interface \"{name}\": {e}", RNS.LOG_ERROR) + return False + + def _detach_interface(self, name, internal_forced=False): + if not internal_forced and not Reticulum.__interface_management_enabled: return False + try: + interfaces = { iface.name: iface for iface in RNS.Transport.interfaces } + if not name in interfaces: + RNS.log(f"Attempt to detach non-existing interface \"{name}\"", RNS.LOG_WARNING) + return None + + else: + interface = interfaces[name] + if isinstance(interface, I2PInterface.I2PInterface): return False + if isinstance(interface, LocalInterface.LocalClientInterface): return False + if isinstance(interface, LocalInterface.LocalServerInterface): return False + if interface.spawned_interfaces: + if type(interface.spawned_interfaces) == dict: spawned = list(interface.spawned_interfaces.values()) + elif type(interface.spawned_interfaces) == list: spawned = interface.spawned_interfaces.copy() + for s in spawned: + s.detach() + s.teardown() + RNS.Transport.remove_interface(s) + + interface.detach() + RNS.Transport.remove_interface(interface) + RNS.log(f"Interface \"{name}\" was detached", RNS.LOG_NOTICE) + return True + + except Exception as e: RNS.log(f"Error while detaching interface \"{name}\": {e}", RNS.LOG_ERROR); RNS.trace_exception(e) + return False + + def _reload_interface(self, name, internal_forced=False): + if not internal_forced and not Reticulum.__interface_management_enabled: return False + interfaces = { iface.name: iface for iface in RNS.Transport.interfaces } + if not name in interfaces: + RNS.log(f"Attempt to reload non-existing interface \"{name}\"", RNS.LOG_WARNING) + return None + + if self._detach_interface(name, internal_forced=internal_forced) and self._attach_interface(name, internal_forced=internal_forced): + RNS.log(f"Interface \"{name}\" was reloaded", RNS.LOG_NOTICE) + return True + + else: + RNS.log(f"Could not reload interface \"{name}\"", RNS.LOG_NOTICE) + return False + + def _synthesize_interface(self, config, name, instance_init=False, force_attach=False): c = config interface_mode = Interface.Interface.MODE_FULL @@ -804,15 +887,19 @@ class Reticulum: ifac_netname = None if "networkname" in c: - if c["networkname"] != "": ifac_netname = c["networkname"] + if c["networkname"] == "None": RNS.log("Ambiguous IFAC network name \"None\", this value is ignored and an IFAC network name has NOT been set", RNS.LOG_WARNING) + if c["networkname"] != "" and c["networkname"] != "None": ifac_netname = c["networkname"] if "network_name" in c: - if c["network_name"] != "": ifac_netname = c["network_name"] + if c["network_name"] == "None": RNS.log("Ambiguous IFAC network name \"None\", this value is ignored and an IFAC network name has NOT been set", RNS.LOG_WARNING) + if c["network_name"] != "" and c["network_name"] != "None": ifac_netname = c["network_name"] ifac_netkey = None if "passphrase" in c: - if c["passphrase"] != "": ifac_netkey = c["passphrase"] + if c["passphrase"] == "None": RNS.log("Ambiguous IFAC passphrase \"None\", this value is ignored and an IFAC passphrase has NOT been set", RNS.LOG_WARNING) + if c["passphrase"] != "" and c["passphrase"] != "None": ifac_netkey = c["passphrase"] if "pass_phrase" in c: - if c["pass_phrase"] != "": ifac_netkey = c["pass_phrase"] + if c["pass_phrase"] == "None": RNS.log("Ambiguous IFAC passphrase \"None\", this value is ignored and an IFAC passphrase has NOT been set", RNS.LOG_WARNING) + if c["pass_phrase"] != "" and c["pass_phrase"] != "None": ifac_netkey = c["pass_phrase"] ingress_control = True if "ingress_control" in c: ingress_control = c.as_bool("ingress_control") @@ -1005,11 +1092,16 @@ class Reticulum: interface.ifac_identity = RNS.Identity.from_bytes(interface.ifac_key) interface.ifac_signature = interface.ifac_identity.sign(RNS.Identity.full_hash(interface.ifac_key)) + elif interface.discoverable and interface.discovery_publish_ifac: + RNS.log(f"IFAC publishing was enabled for discoverable interface {interface}, but neither IFAC netname nor passphrase is configured", RNS.LOG_WARNING) + RNS.log(f"Disabling IFAC publishing for {interface}", RNS.LOG_WARNING) + interface.discovery_publish_ifac = False + RNS.Transport.add_interface(interface) interface.final_init() interface = None - if (("interface_enabled" in c) and c.as_bool("interface_enabled") == True) or (("enabled" in c) and c.as_bool("enabled") == True): + if (("interface_enabled" in c) and c.as_bool("interface_enabled") == True) or (("enabled" in c) and c.as_bool("enabled") == True) or force_attach: interface_config = c interface_config["name"] = name interface_config["selected_interface_mode"] = interface_mode @@ -1113,7 +1205,6 @@ class Reticulum: except Exception as e: RNS.log(f"External interface initialisation failed for {interface_type} / {name}", RNS.LOG_ERROR) RNS.trace_exception(e) - else: RNS.log("Skipping disabled interface \""+name+"\"", RNS.LOG_DEBUG) @@ -1300,6 +1391,12 @@ class Reticulum: if path == "blackholed_identities": self.rpc_return(conn, self.get_blackholed_identities()) if path == "is_blackholed": self.rpc_return(conn, self.is_blackholed(call["identity_hash"])) + if "manage" in call: + path = call["manage"] + if path == "attach_interface": self.rpc_return(conn, self.attach_interface(call["name"])) + if path == "detach_interface": self.rpc_return(conn, self.detach_interface(call["name"])) + if path == "reload_interface": self.rpc_return(conn, self.reload_interface(call["name"])) + if "drop" in call: path = call["drop"] if path == "path": self.rpc_return(conn, self.drop_path(call["destination_hash"])) @@ -1867,21 +1964,39 @@ class Reticulum: if RNS.Profiler.ran(): return RNS.Profiler.results() else: return None - def halt_interface(self, interface): - pass + def attach_interface(self, interface_name): + if self.is_connected_to_shared_instance: + rpc_connection = self.get_rpc_client() + rpc_connection.send_bytes(mp.packb({"manage": "attach_interface", "name": interface_name})) + response = mp.unpackb(rpc_connection.recv_bytes()) + return response + + else: return self._attach_interface(interface_name) - def resume_interface(self, interface): - pass + def detach_interface(self, interface_name): + if self.is_connected_to_shared_instance: + rpc_connection = self.get_rpc_client() + rpc_connection.send_bytes(mp.packb({"manage": "detach_interface", "name": interface_name})) + response = mp.unpackb(rpc_connection.recv_bytes()) + return response + + else: return self._detach_interface(interface_name) - def reload_interface(self, interface): - pass + def reload_interface(self, interface_name): + if self.is_connected_to_shared_instance: + rpc_connection = self.get_rpc_client() + rpc_connection.send_bytes(mp.packb({"manage": "reload_interface", "name": interface_name})) + response = mp.unpackb(rpc_connection.recv_bytes()) + return response + + else: return self._reload_interface(interface_name) def get_blackholed_identities(self): if self.is_connected_to_shared_instance: - rpc_connection = self.get_rpc_client() - rpc_connection.send_bytes(mp.packb({"get": "blackholed_identities"})) - response = mp.unpackb(rpc_connection.recv_bytes()) - return response + rpc_connection = self.get_rpc_client() + rpc_connection.send_bytes(mp.packb({"get": "blackholed_identities"})) + response = mp.unpackb(rpc_connection.recv_bytes()) + return response else: return RNS.Transport.blackholed_identities @@ -1892,10 +2007,10 @@ class Reticulum: if len(identity_hash) != RNS.Reticulum.TRUNCATED_HASHLENGTH//8: raise ValueError("Invalid identity hash length for blackhole check") if self.is_connected_to_shared_instance: - rpc_connection = self.get_rpc_client() - rpc_connection.send_bytes(mp.packb({"get": "is_blackholed", "identity_hash": identity_hash})) - response = mp.unpackb(rpc_connection.recv_bytes()) - return response + rpc_connection = self.get_rpc_client() + rpc_connection.send_bytes(mp.packb({"get": "is_blackholed", "identity_hash": identity_hash})) + response = mp.unpackb(rpc_connection.recv_bytes()) + return response else: return identity_hash in RNS.Transport.blackholed_identities @@ -2032,6 +2147,10 @@ class Reticulum: def should_autoconnect_discovered_interfaces(): return Reticulum.__autoconnect_discovered_interfaces > 0 + @staticmethod + def should_autoconnect_unverified_implementations(): + return Reticulum.__autoconnect_unverified + @staticmethod def autoconnect_interface_mode(): return Reticulum.__autoconnect_interface_mode diff --git a/RNS/Transport.py b/RNS/Transport.py index ca4fab8f..2a46569f 100755 --- a/RNS/Transport.py +++ b/RNS/Transport.py @@ -1521,7 +1521,7 @@ class Transport: # TODO: Rethink whether this is actually optimal. if packet.hops > 0: - if not hasattr(interface, "announce_cap"): interface.announce_cap = RNS.Reticulum.ANNOUNCE_CAP + if not hasattr(interface, "announce_cap"): interface.announce_cap = RNS.Reticulum.ANNOUNCE_CAP/100.0 if not hasattr(interface, "announce_allowed_at"): interface.announce_allowed_at = 0 if not hasattr(interface, "announce_queue"): interface.announce_queue = [] @@ -3299,7 +3299,7 @@ class Transport: packet = RNS.Packet(path_request_dst, path_request_data, packet_type = RNS.Packet.DATA, transport_type = RNS.Transport.BROADCAST, header_type = RNS.Packet.HEADER_1, attached_interface = on_interface) if on_interface != None and recursive: - if not hasattr(on_interface, "announce_cap"): on_interface.announce_cap = RNS.Reticulum.ANNOUNCE_CAP + if not hasattr(on_interface, "announce_cap"): on_interface.announce_cap = RNS.Reticulum.ANNOUNCE_CAP/100.0 if not hasattr(on_interface, "announce_allowed_at"): on_interface.announce_allowed_at = 0 if not hasattr(on_interface, "announce_queue"): on_interface.announce_queue = [] diff --git a/RNS/Utilities/rngit/media.py b/RNS/Utilities/rngit/media.py new file mode 100644 index 00000000..75008c29 --- /dev/null +++ b/RNS/Utilities/rngit/media.py @@ -0,0 +1,239 @@ +# Reticulum License +# +# Copyright (c) 2016-2026 Mark Qvist +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# - The Software shall not be used in any kind of system which includes amongst +# its functions the ability to purposefully do harm to human beings. +# +# - The Software shall not be used, directly or indirectly, in the creation of +# an artificial intelligence, machine learning or language model training +# dataset, including but not limited to any use that contributes to the +# training or development of such a model or algorithm. +# +# - The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import os +import time +import shutil +import subprocess +import tempfile +import RNS + +CONVERSION_TIMEOUT = 8 + +# WebP encoding backends, in preference order. All supported +# encoder families handle the common still formats (PNG, JPEG, +# TIFF, BMP, GIF, WebP). +# +# Environment overrides: +# RNGIT_MEDIA_BACKEND force a specific backend + +BACKENDS = ( ("magick", ["magick", "-", "webp:-"]), + ("convert", ["convert", "-", "webp:-"]), + ("gm", ["gm", "convert", "-", "webp:-"]), + ("ffmpeg", ["ffmpeg", "-y", "-loglevel", "error", "-i", "-", "-f", "webp", "pipe:1"]), + ("avconv", ["avconv", "-y", "-loglevel", "error", "-i", "-", "-f", "webp", "pipe:1"]) ) + +_ENV_BACKEND = os.environ.get("RNGIT_MEDIA_BACKEND") +_winner = None +_no_backend_logged = False + +def available_backends(): + out = [] + for name, argv in BACKENDS: out.append((name, shutil.which(argv[0]) is not None)) + return out + +def _selected_backend(): + global _winner + if _ENV_BACKEND: + for name, argv in BACKENDS: + if name == _ENV_BACKEND and shutil.which(argv[0]) is not None: + return (name, argv) + return None + + order = list(BACKENDS) + if _winner is not None: order.sort(key=lambda backend: backend[0] != _winner) + + for name, argv in order: + if shutil.which(argv[0]) is not None: + _winner = name + return (name, argv) + + return None + +def _terminate(proc): + try: proc.kill() + except Exception: pass + try: proc.wait() + except Exception: pass + +def _stderr_tail(proc, limit=1024): + try: + data = proc.stderr.read(limit) + return data.decode("utf-8", "replace").strip() + except Exception: return "" + +def _webp_info(data): + if len(data) < 30 or data[:4] != b"RIFF" or data[8:12] != b"WEBP": return None + fourcc = data[12:16] + if fourcc == b"VP8X": + width = int.from_bytes(data[24:27], "little") + 1 + height = int.from_bytes(data[27:30], "little") + 1 + elif fourcc == b"VP8 ": + width = int.from_bytes(data[26:28], "little") & 0x3FFF + height = int.from_bytes(data[28:30], "little") & 0x3FFF + elif fourcc == b"VP8L": + bits = int.from_bytes(data[21:25], "little") + width = (bits & 0x3FFF) + 1 + height = ((bits >> 14) & 0x3FFF) + 1 + else: return None + if width > 0 and height > 0: return (width, height) + return None + +def _valid_webp(path): + try: + with open(path, "rb") as fh: return _webp_info(fh.read(30)) is not None + except Exception: return False + +def _unlink_output(path): + try: os.unlink(path) + except Exception: pass + +def _configured_backend(quality=None, max_dimension=None): + global _no_backend_logged + backend = _selected_backend() + if backend is None: + if not _no_backend_logged: + _no_backend_logged = True + RNS.log("No WebP encoding backend available for media conversion. You can Install ImageMagick or ffmpeg to enable image conversion.", RNS.LOG_WARNING) + return None + + backend_name, encoder_argv = backend + _no_backend_logged = False + + quality_arg = None + dimension_arg = None + if quality is not None: + try: quality_arg = max(1, min(100, int(quality))) + except (ValueError, TypeError): pass + if max_dimension is not None: + try: dimension_arg = int(max_dimension) + except (ValueError, TypeError): pass + if dimension_arg is not None and dimension_arg < 1: dimension_arg = None + + encoder_argv = list(encoder_argv) + if backend_name in ("magick", "convert", "gm"): + options = [] + if quality_arg is not None: options += ["-quality", str(quality_arg)] + if dimension_arg is not None: options += ["-resize", f"{dimension_arg}x{dimension_arg}>"] + encoder_argv = encoder_argv[:-1] + options + encoder_argv[-1:] + elif backend_name in ("ffmpeg", "avconv"): + options = [] + if quality_arg is not None: options += ["-quality", str(quality_arg)] + if dimension_arg is not None: options += ["-vf", f"scale='min(iw,{dimension_arg})':'min(ih,{dimension_arg})':force_original_aspect_ratio=decrease"] + try: format_index = encoder_argv.index("-f") + except ValueError: format_index = len(encoder_argv) + encoder_argv = encoder_argv[:format_index] + options + encoder_argv[format_index:] + + return backend_name, encoder_argv + +def _await(backend_name, encoder_proc, input_proc=None, timeout=None): + if timeout is None: timeout = CONVERSION_TIMEOUT + + deadline = time.time() + timeout + try: + encoder_proc.wait(timeout=max(0.0, deadline - time.time())) + if input_proc is not None: input_proc.wait(timeout=max(0.0, deadline - time.time())) + except subprocess.TimeoutExpired: + _terminate(input_proc) + _terminate(encoder_proc) + RNS.log(f"Media conversion via {backend_name} timed out after {timeout} seconds", RNS.LOG_WARNING) + return False + + if encoder_proc.returncode != 0: + detail = "" + encoder_tail = _stderr_tail(encoder_proc) + input_tail = _stderr_tail(input_proc) if input_proc is not None else "" + if encoder_tail: detail += f" Encoder: {encoder_tail}" + if input_tail: detail += f" Input: {input_tail}" + RNS.log(f"Media conversion via {backend_name} failed.{detail}", RNS.LOG_WARNING) + return False + + return True + +def convert_to_webp(input_argv, output_path, cwd=None, timeout=None, quality=None, max_dimension=None): + configured = _configured_backend(quality=quality, max_dimension=max_dimension) + if configured is None: return False + + backend_name, encoder_argv = configured + + try: + with open(output_path, "wb") as output_fh: + input_proc = subprocess.Popen(input_argv, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + encoder_proc = subprocess.Popen(encoder_argv, stdin=input_proc.stdout, stdout=output_fh, stderr=subprocess.PIPE) + + # The parent must not retain a copy of the input pipe's write + # end, or the input process would never see EOF. + input_proc.stdout.close() + if not _await(backend_name, encoder_proc, input_proc=input_proc, timeout=timeout): return False + + if not _valid_webp(output_path): + RNS.log(f"Media conversion via {backend_name} produced invalid WebP output", RNS.LOG_WARNING) + return False + + RNS.log(f"Media converted to WebP with {backend_name}", RNS.LOG_DEBUG) + return True + + except Exception as e: + RNS.log(f"Error during media conversion: {e}", RNS.LOG_WARNING) + return False + +def convert_file_to_webp(source_path, quality=85, max_dimension=None, timeout=None): + configured = _configured_backend(quality=quality, max_dimension=max_dimension) + if configured is None: return False + backend_name, encoder_argv = configured + + tmp_path = None + success = False + try: + if not os.path.isfile(source_path): + RNS.log(f"Cannot convert media: source file does not exist: {source_path}", RNS.LOG_WARNING) + return False + + fd, tmp_path = tempfile.mkstemp(prefix="rns_media_", suffix=".webp") + os.close(fd) + + with open(source_path, "rb") as input_fh, open(tmp_path, "wb") as output_fh: + encoder_proc = subprocess.Popen(encoder_argv, stdin=input_fh, stdout=output_fh, stderr=subprocess.PIPE) + if not _await(backend_name, encoder_proc, timeout=timeout): return False + + if not _valid_webp(tmp_path): + RNS.log(f"Invalid media conversion output from {backend_name}", RNS.LOG_WARNING) + return False + + success = True + RNS.log(f"Media converted to WebP with {backend_name}", RNS.LOG_DEBUG) + return tmp_path + + except Exception as e: + RNS.log(f"Error during media conversion: {e}", RNS.LOG_WARNING) + return False + + finally: + if not success and tmp_path is not None: _unlink_output(tmp_path) diff --git a/RNS/Utilities/rngit/pages.py b/RNS/Utilities/rngit/pages.py index faad08e9..7df5863b 100644 --- a/RNS/Utilities/rngit/pages.py +++ b/RNS/Utilities/rngit/pages.py @@ -32,13 +32,14 @@ import os import time import threading import subprocess +import tempfile import urllib.parse import RNS import struct import base64 from collections import deque from datetime import datetime -from RNS.Utilities.rngit import APP_NAME +from RNS.Utilities.rngit import APP_NAME, media from RNS.Utilities.rngit.util import MarkdownToMicron, san_sha from RNS.Utilities.rngit.highlight import SyntaxHighlighter from RNS.vendor.configobj import ConfigObj @@ -50,6 +51,7 @@ from RNS.Utilities.rngit.commitsigs import unarmor_ssh_signature, parse_ssh_sign class NomadNetworkNode(): APP_NAME = "nomadnetwork" JOBS_INTERVAL = 5 + LINK_CLEAN_INTERVAL = 60 PATH_INDEX = "/page/index.mu" PATH_GROUP = "/page/group.mu" @@ -64,6 +66,7 @@ class NomadNetworkNode(): PATH_RELEASE = "/page/release.mu" PATH_WORK = "/page/work.mu" PATH_WORK_DOC = "/page/work_doc.mu" + PATH_MEDIA = "/media" FILE_ARTIFACT = "/file/artifact" FILE_DOWNLOAD = "/file/download" FILE_WORKDOC = "/file/workdoc" @@ -120,8 +123,10 @@ class NomadNetworkNode(): # want to use tabs, three spaces is all you get. TAB_WIDTH = " " - RENDERABLE_EXTS = [".md", ".mu"] - RENDER_DEFAULT = [".md", ".mu"] + CONVERTABLE_EXTS = [".md"] + RENDERABLE_EXTS = [".md", ".mu"] + RENDER_DEFAULT = [".md", ".mu"] + IMAGE_EXTS = [".webp", ".png", ".jpg", ".jpeg", ".gif", ".tiff", ".tif", ".bmp"] def __init__(self, owner=None): if not owner: raise TypeError(f"Invalid owner {owner} for {self}") @@ -150,12 +155,16 @@ class NomadNetworkNode(): self.templates["stats"] = DEFAULT_STATS_TEMPLATE self.templates["work"] = DEFAULT_WORK_TEMPLATE self.templates["work_doc"] = DEFAULT_WORK_DOC_TEMPLATE + self.templates["no_ident"] = DEFAULT_NO_IDENT_TEMPLATE self.templatesdir = self.owner.configdir+"/templates" self.use_nerdfonts = self.USE_NERDFONTS + self.media_conversion = True self.highlight_syntax = True self.highlighter = SyntaxHighlighter() self.mdc = MarkdownToMicron(max_width=self.MAX_RENDER_WIDTH, syntax_highlighter=self.highlighter) self.thanks_deque = deque(maxlen=256) + self.active_links = {} + self.last_link_clean = 0 if not os.path.isdir(self.templatesdir): try: os.makedirs(self.templatesdir) @@ -164,6 +173,8 @@ class NomadNetworkNode(): if "pages" in self.owner.config: if "unicode_icons" in self.owner.config["pages"]: if self.owner.config["pages"].as_bool("unicode_icons"): self.use_nerdfonts = False + if "media_conversion" in self.owner.config["pages"]: + self.media_conversion = self.owner.config["pages"].as_bool("media_conversion") self.destination = RNS.Destination(self.identity, RNS.Destination.IN, RNS.Destination.SINGLE, self.APP_NAME, "node") self.destination.set_link_established_callback(self.remote_connected) @@ -210,6 +221,10 @@ class NomadNetworkNode(): try: if self.announce_interval and time.time() > self.last_announce + self.announce_interval: self.announce() + if time.time() > self.last_link_clean + self.LINK_CLEAN_INTERVAL: + self.clean_links() + self.last_link_clean = time.time() + except Exception as e: RNS.log(f"Error while running periodic jobs: {e}", RNS.LOG_ERROR) def get_announce_app_data(self): return self.node_name.encode("utf-8") @@ -246,6 +261,7 @@ class NomadNetworkNode(): self.destination.register_request_handler(self.PATH_RELEASE, response_generator=self.serve_release_page, allow=RNS.Destination.ALLOW_ALL) self.destination.register_request_handler(self.PATH_WORK, response_generator=self.serve_work_page, allow=RNS.Destination.ALLOW_ALL) self.destination.register_request_handler(self.PATH_WORK_DOC, response_generator=self.serve_work_doc_page, allow=RNS.Destination.ALLOW_ALL) + self.destination.register_request_handler(self.PATH_MEDIA, response_generator=self.serve_media, allow=RNS.Destination.ALLOW_ALL, auto_compress=False) self.destination.register_request_handler(self.FILE_ARTIFACT, response_generator=self.serve_artifact, allow=RNS.Destination.ALLOW_ALL) self.destination.register_request_handler(self.FILE_DOWNLOAD, response_generator=self.serve_download, allow=RNS.Destination.ALLOW_ALL) self.destination.register_request_handler(self.FILE_WORKDOC, response_generator=self.serve_wd_download, allow=RNS.Destination.ALLOW_ALL) @@ -372,6 +388,10 @@ class NomadNetworkNode(): self.owner.view_succeeded(None, None, remote_identity) page_content = "".join(content_parts) nav_content = "".join(nav_parts) + + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", nav_content=nav_content, st=st) + return self.render_template(page_content, nav_content=nav_content, template="front", st=st) def serve_group_page(self, path, data, request_id, link_id, remote_identity, requested_at): @@ -392,6 +412,9 @@ class NomadNetworkNode(): nav_parts.append(breadcrumb + "\n") nav_content = "".join(nav_parts) + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", nav_content=nav_content, st=st) + accessible_repos = self.get_accessible_repositories(remote_identity, group_name) if not group_name or group_name not in self.owner.groups or not accessible_repos: @@ -441,6 +464,9 @@ class NomadNetworkNode(): repo = self.get_accessible_repository(remote_identity, group_name, repo_name) + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", nav_content="".join(nav_parts), st=st) + if not repo: content = self.m_heading("Not Found", 1) + "\nThe requested repository was not found.\n" return self.render_template(content, nav_content="".join(nav_parts), st=st) @@ -554,6 +580,9 @@ class NomadNetworkNode(): except (ValueError, TypeError): page_num = 0 + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) + repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: content = self.m_heading("Not Found", 1) + "\n\nThe requested repository does not exist or you do not have access to it.\n" @@ -691,6 +720,9 @@ class NomadNetworkNode(): render = True if render else False raw = True if raw else False + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) + repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: content = self.m_heading("Not Found", 1) + "\n\nThe requested repository does not exist or you do not have access to it.\n" @@ -712,6 +744,7 @@ class NomadNetworkNode(): file_path = file_path.removeprefix("./").replace("/./", "/") file_ext = os.path.splitext(file_path)[1].lower() renderable = file_ext in self.RENDERABLE_EXTS + convertable = file_ext in self.CONVERTABLE_EXTS if not renderable: raw = True; render = False else: if raw: render = False @@ -738,14 +771,16 @@ class NomadNetworkNode(): nav_parts.append(">>\n" + breadcrumb + "\n") sep = self.icon("sep") - dl_link = self.m_link("Download", self.FILE_DOWNLOAD, g=group_name, r=repo_name, ref=ref, path=file_path) + dl_link = self.m_link("Download", self.FILE_DOWNLOAD, g=group_name, r=repo_name, ref=ref, path=file_path) if not renderable: nav_parts.append(f"\nDisplaying Raw {sep} {dl_link}\n") else: rnd_link = self.m_link("View rendered", self.PATH_BLOB, g=group_name, r=repo_name, ref=ref, path=file_path, render="y") raw_link = self.m_link("View raw", self.PATH_BLOB, g=group_name, r=repo_name, ref=ref, path=file_path, raw="y") + mu_link = self.m_link("as micron", self.FILE_DOWNLOAD, g=group_name, r=repo_name, ref=ref, path=file_path, fmt="mu") if render: render_controls = f"Displaying Rendered {sep} {raw_link}" else: render_controls = f"Displaying Raw {sep} {rnd_link}" - nav_parts.append(f"\n{render_controls} {sep} {dl_link}\n") + if convertable: nav_parts.append(f"\n{render_controls} {sep} {dl_link} {self.CLR_DIM}{mu_link}`f\n") + else: nav_parts.append(f"\n{render_controls} {sep} {dl_link}\n") # Get blob info blob_info = self.get_blob_info(repo_path, resolved_ref, file_path) @@ -771,8 +806,9 @@ class NomadNetworkNode(): content_parts.append(f"`*{self.m_escape(symlink_target or 'unknown')}`*\n") elif is_binary: - content_parts.append("This file appears to be binary and cannot be displayed as text.\n") - # TODO: Implement raw file downloads + if file_ext in self.IMAGE_EXTS: + content_parts.append(f"`(Image file`w=n`a=c`:/media/{group_name}/{repo_name}/{ref}/{urllib.parse.quote_plus(file_path)})\n") + else: content_parts.append("This file appears to be binary and cannot be displayed as text.\n") elif size > self.BLOB_SIZE_LIMIT: content_parts.append(f"This file is {RNS.prettysize(size)}, which exceeds the display limit of {RNS.prettysize(self.BLOB_SIZE_LIMIT)}.\n") @@ -823,6 +859,9 @@ class NomadNetworkNode(): except (ValueError, TypeError): page_num = 0 + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) + repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: content = self.m_heading("Not Found", 1) + "\n\nThe requested repository does not exist or you do not have access to it.\n" @@ -902,6 +941,9 @@ class NomadNetworkNode(): content = self.m_heading("Error", 2) + "\nInvalid request\n" return self.render_template(content, st=st) + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) + repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: content = self.m_heading("Error", 2) + "\nThe requested repository was not found.\n" @@ -1057,6 +1099,9 @@ class NomadNetworkNode(): nav_parts.append(">>\n" + breadcrumb + "\n") nav_content = "".join(nav_parts) + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) + if not group_name or not repo_name: content = self.m_heading("Error", 2) + "\nInvalid request\n" return self.render_template(content, st=st) @@ -1155,6 +1200,9 @@ class NomadNetworkNode(): if not group_name or not repo_name: content = self.m_heading("Error", 2) + "\nInvalid request\n" return self.render_template(content, st=st) + + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) content_parts = [] nav_parts = [] @@ -1256,6 +1304,9 @@ class NomadNetworkNode(): content = self.m_heading("Error", 2) + "\nInvalid request\n" return self.render_template(content, st=st) + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) + repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: content = self.m_heading("Error", 2) + "\nThe requested repository was not found.\n" @@ -1320,6 +1371,9 @@ class NomadNetworkNode(): content = self.m_heading("Error", 2) + "\nInvalid request\n" return self.render_template(content, st=st) + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) + repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: content = self.m_heading("Error", 2) + "\nThe requested repository was not found.\n" @@ -1422,11 +1476,17 @@ class NomadNetworkNode(): content = self.m_heading("Error", 2) + "\nInvalid request\n" return self.render_template(content, st=st) + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) + repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: content = self.m_heading("Error", 2) + "\nThe requested repository was not found.\n" return self.render_template(content, st=st) + work_path = f"{repo['path']}.work" + scopes_to_show = ["active", "completed", "proposed"] if scope == "all" else [scope] + content_parts = [] nav_parts = [] @@ -1441,17 +1501,46 @@ class NomadNetworkNode(): cmplt_s = "`_" if scope == "completed" else "" prpsd_s = "`_" if scope == "proposed" else "" all_s = "`_" if scope == "all" else "" + + # Count work documents + scope_counts = {"active": 0, "completed": 0, "proposed": 0} + for s in ["active", "completed", "proposed"]: + try: + folder_path = os.path.join(work_path, s) + if os.path.isdir(folder_path): + for entry in os.listdir(folder_path): + try: + doc_dir = os.path.join(folder_path, entry) + if not os.path.isdir(doc_dir): continue + + doc_id = int(entry) + read_access = self.resolve_doc_permission(remote_identity, group_name, repo_name, doc_id, self.owner.PERM_READ) + if not read_access: continue + + root_path = os.path.join(doc_dir, "root") + if not os.path.isfile(root_path): continue + scope_counts[s] += 1 + except Exception as e: RNS.trace_exception(e) + except Exception as e: RNS.trace_exception(e) + + force_counts = True + adc = scope_counts['active'] + cdc = scope_counts['completed'] + pdc = scope_counts['proposed'] + tdc = adc+cdc+pdc + adc_str = f" ({adc})" if force_counts or (not scope == "active" and adc) else "" + cdc_str = f" ({cdc})" if force_counts or (not scope == "completed" and cdc) else "" + pdc_str = f" ({pdc})" if force_counts or (not scope == "proposed" and pdc) else "" + tdc_str = f" ({tdc})" if force_counts or (not scope == "all" and tdc) else "" + filter_links = [] - filter_links.append(active_s+self.m_link("Active", self.PATH_WORK, g=group_name, r=repo_name, scope="active")+active_s) - filter_links.append(cmplt_s+self.m_link("Completed", self.PATH_WORK, g=group_name, r=repo_name, scope="completed")+cmplt_s) - filter_links.append(prpsd_s+self.m_link("Proposed", self.PATH_WORK, g=group_name, r=repo_name, scope="proposed")+prpsd_s) - filter_links.append(all_s+self.m_link("All", self.PATH_WORK, g=group_name, r=repo_name, scope="all")+all_s) + filter_links.append(active_s+self.m_link("Active", self.PATH_WORK, g=group_name, r=repo_name, scope="active")+active_s+adc_str) + filter_links.append(cmplt_s+self.m_link("Completed", self.PATH_WORK, g=group_name, r=repo_name, scope="completed")+cmplt_s+cdc_str) + filter_links.append(prpsd_s+self.m_link("Proposed", self.PATH_WORK, g=group_name, r=repo_name, scope="proposed")+prpsd_s+pdc_str) + filter_links.append(all_s+self.m_link("All", self.PATH_WORK, g=group_name, r=repo_name, scope="all")+all_s+tdc_str) content_parts.append(f" {sep} ".join(filter_links) + "\n\n") # Load work documents - work_path = f"{repo['path']}.work" - scopes_to_show = ["active", "completed", "proposed"] if scope == "all" else [scope] - for s in scopes_to_show: folder_path = os.path.join(work_path, s) @@ -1483,11 +1572,11 @@ class NomadNetworkNode(): docs.sort(key=lambda x: max(x["created"], x["edited"]), reverse=True) if not docs: - content_parts.append(self.m_heading(f"{s.capitalize()} ({len(docs)})", 2)+f"\n`*No {s} work documents`*\n") + content_parts.append(self.m_heading(f"{s.capitalize()}", 2)+f"\n`*No {s} work documents`*\n") content_parts.append("\n") else: - content_parts.append(self.m_heading(f"{s.capitalize()} ({len(docs)})", 2)) + content_parts.append(self.m_heading(f"{s.capitalize()}", 2)) content_parts.append("\n") for doc in docs: @@ -1522,6 +1611,9 @@ class NomadNetworkNode(): content = self.m_heading("Error", 2) + "\nInvalid request\n" return self.render_template(content, st=st) + if not remote_identity and self.null_ident.hash in self.owner.blocked_identities: + return self.render_template("", template="no_ident", st=st) + try: doc_id = int(doc_id) except: content = self.m_heading("Error", 2) + "\nInvalid document ID\n" @@ -1671,7 +1763,7 @@ class NomadNetworkNode(): repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: - RNS.log(f"Repository not found or no access for artifact request {group_name}/{repo_name}/{tag}/{artifact}", RNS.LOG_WARNING) + RNS.log(f"Repository not found or no access for artifact request {group_name}/{repo_name}/{tag}/{artifact}", RNS.LOG_DEBUG) return None releases_path = f"{repo['path']}.releases" @@ -1715,6 +1807,69 @@ class NomadNetworkNode(): self.owner.release_download_succeeded(group_name, repo_name, remote_identity) return [open(artifact_path, "rb"), {"name": artifact.encode("utf-8")}] + def serve_media(self, path, data, request_id, link_id, remote_identity, requested_at): + st = time.time() + RNS.log(f"Media request from {remote_identity}", RNS.LOG_DEBUG) + + if not data or not type(data) == dict: data = {} + if not "key" in data: + RNS.log(f"Missing request key in media request", RNS.LOG_DEBUG) + return False + + media_path = data.get("path", None) + if not media_path: + RNS.log(f"Missing path in media request", RNS.LOG_DEBUG) + return False + + comps = media_path.removeprefix("/media").lstrip("/").split("/") + if len(comps) < 4: + RNS.log(f"Insufficient path components in media request", RNS.LOG_DEBUG) + return False + + group_name = comps[0] + repo_name = comps[1] + ref = comps[2] + file_path = "/".join(comps[3:]) + file_path = urllib.parse.unquote_plus(file_path) + file_name = os.path.basename(file_path) + + repo = self.get_accessible_repository(remote_identity, group_name, repo_name) + if not repo: + RNS.log(f"Repository not found or no access for media request {group_name}/{repo_name}/{ref}/{file_path}", RNS.LOG_DEBUG) + return False + + repo_path = repo["path"] + + resolved_ref = self.resolve_ref(repo_path, ref) + if not resolved_ref: + RNS.log(f"Ref not found for media request {group_name}/{repo_name}/{ref}/{file_path}", RNS.LOG_WARNING) + return False + + if not file_path: + RNS.log(f"No file path for media request {group_name}/{repo_name}/{ref}/{file_path}", RNS.LOG_WARNING) + return False + + blob_info = self.get_blob_info(repo_path, resolved_ref, file_path) + if blob_info is None: + RNS.log(f"File not found at ref for media request {group_name}/{repo_name}/{ref}/{file_path}", RNS.LOG_WARNING) + return False + + else: + stream = None + response_name = file_name + file_ext = os.path.splitext(file_path)[1].lower() + if self.media_conversion and file_ext in self.IMAGE_EXTS and file_ext != ".webp": + converted = self.get_webp_stream(repo_path, resolved_ref, file_path, link_id) + if converted: stream, response_name = converted + + if not stream: stream = self.get_blob_stream(repo_path, resolved_ref, file_path) + if stream: return [stream, {"name": response_name.encode("utf-8")}] + else: + RNS.log(f"Could not resolve blob stream for media request {group_name}/{repo_name}/{ref}/{file_path}", RNS.LOG_WARNING) + return None + + return None + def serve_download(self, path, data, request_id, link_id, remote_identity, requested_at): st = time.time() RNS.log(f"File download request from {remote_identity}", RNS.LOG_DEBUG) @@ -1723,13 +1878,19 @@ class NomadNetworkNode(): group_name = data.get("var_g", "") if data else "" repo_name = data.get("var_r", "") if data else "" ref = data.get("var_ref", "HEAD") if data else "HEAD" + file_fmt = data.get("var_fmt", "") if data else "" file_path = data.get("var_path", "") if data else "" file_path = urllib.parse.unquote_plus(file_path) file_name = os.path.basename(file_path) + file_ext = os.path.splitext(file_path)[1].lower() + convertable = file_ext in self.CONVERTABLE_EXTS + if file_fmt and not convertable: + RNS.log(f"Download conversion request for non-convertable file", RNS.LOG_DEBUG) + return None repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: - RNS.log(f"Repository not found or no access for download request {group_name}/{repo_name}/{ref}/{file_path}", RNS.LOG_WARNING) + RNS.log(f"Repository not found or no access for download request {group_name}/{repo_name}/{ref}/{file_path}", RNS.LOG_DEBUG) return None repo_path = repo["path"] @@ -1752,7 +1913,47 @@ class NomadNetworkNode(): stream = self.get_blob_stream(repo_path, resolved_ref, file_path) if stream is not None: self.owner.download_succeeded(group_name, repo_name, remote_identity) - return [stream, {"name": file_name.encode("utf-8")}] + if not file_fmt: return [stream, {"name": file_name.encode("utf-8")}] + elif file_fmt == "mu": + link = self.active_links.get(link_id) + if not link: + RNS.log(f"Could not resolve link for file conversion of {file_path}", RNS.LOG_WARNING) + return None + + if not hasattr(link, "temporary_directories"): link.temporary_directories = [] + tmpdir = tempfile.TemporaryDirectory() + link.temporary_directories.append(tmpdir) + + stem = os.path.splitext(os.path.basename(file_path))[0] + response_name = stem + ".mu" + + try: + path_components = file_path.strip("/").split("/") + path = "/".join(path_components[:-1])+"/" if len(path_components) > 1 else "" + url_scope = f":/page/blob.mu`g={group_name}|r={repo_name}|ref={ref}|path={path}" + mdc = MarkdownToMicron(max_width=self.MAX_RENDER_WIDTH, syntax_highlighter=self.highlighter, url_scope=url_scope) + mu = mdc.format_block(stream.read().decode("utf-8")).rstrip().encode("utf-8") + + if not mu: + if tmpdir in link.temporary_directories: link.temporary_directories.remove(tmpdir) + tmpdir.cleanup() + return None + + fd, spool_path = tempfile.mkstemp(prefix=stem+".", suffix=".mu", dir=tmpdir.name) + os.close(fd) + with open(spool_path, "wb") as f: f.write(mu) + + spool = open(spool_path, "rb") + return [spool, {"name": f"{os.path.splitext(file_name)[0]}.mu".encode("utf-8")}] + + except Exception as e: + RNS.log(f"Error during file conversion of {file_path} for {link}: {e}", RNS.LOG_WARNING) + if tmpdir in link.temporary_directories: link.temporary_directories.remove(tmpdir) + try: tmpdir.cleanup() + except Exception: pass + return None + + else: return None else: RNS.log(f"Could not resolve blob stream for download request {group_name}/{repo_name}/{ref}/{file_path}", RNS.LOG_WARNING) @@ -1783,7 +1984,7 @@ class NomadNetworkNode(): repo = self.get_accessible_repository(remote_identity, group_name, repo_name) if not repo: - RNS.log(f"Repository not found or no access for workdoc download request {group_name[:128]}/{repo_name[:128]}/{doc_id}", RNS.LOG_WARNING) + RNS.log(f"Repository not found or no access for workdoc download request {group_name[:128]}/{repo_name[:128]}/{doc_id}", RNS.LOG_DEBUG) return None doc_access = self.resolve_doc_permission(remote_identity, group_name, repo_name, doc_id, self.owner.PERM_READ) @@ -2084,6 +2285,40 @@ class NomadNetworkNode(): return None + def get_webp_stream(self, repo_path, ref, file_path, link_id): + file_path = file_path.strip("/") + link = self.active_links.get(link_id) + if not link: + RNS.log(f"Could not resolve link for media conversion of {file_path}", RNS.LOG_WARNING) + return None + + if not hasattr(link, "temporary_directories"): link.temporary_directories = [] + tmpdir = tempfile.TemporaryDirectory() + link.temporary_directories.append(tmpdir) + + stem = os.path.splitext(os.path.basename(file_path))[0] + response_name = stem + ".webp" + + try: + fd, spool_path = tempfile.mkstemp(prefix=stem+".", suffix=".webp", dir=tmpdir.name) + os.close(fd) + + converted = media.convert_to_webp(["git", "show", f"{ref}:{file_path}"], spool_path, cwd=repo_path) + if not converted: + if tmpdir in link.temporary_directories: link.temporary_directories.remove(tmpdir) + tmpdir.cleanup() + return None + + spool = open(spool_path, "rb") + return spool, response_name + + except Exception as e: + RNS.log(f"Error during media conversion of {file_path} for {link}: {e}", RNS.LOG_WARNING) + if tmpdir in link.temporary_directories: link.temporary_directories.remove(tmpdir) + try: tmpdir.cleanup() + except Exception: pass + return None + def get_refs_info(self, repo_path, default_branch=None): refs = {"heads": [], "tags": []} @@ -2695,11 +2930,38 @@ class NomadNetworkNode(): def remote_connected(self, link): RNS.log(f"Peer connected to {self.destination}", RNS.LOG_DEBUG) + self.active_links[link.link_id] = link link.set_remote_identified_callback(self.remote_identified) link.set_link_closed_callback(self.remote_disconnected) def remote_disconnected(self, link): RNS.log(f"Peer disconnected from {self.destination}", RNS.LOG_DEBUG) + if link.link_id in self.active_links: self.active_links.pop(link.link_id) + self.cleanup_link_temporary_resources(link) + + def clean_links(self): + stale_links = [] + for link_id, link in self.active_links.items(): + if not link.status == RNS.Link.ACTIVE: stale_links.append(link_id) + + cleaned_links = 0 + for link_id in stale_links: + link = self.active_links.pop(link_id, None) + if link: + self.cleanup_link_temporary_resources(link) + cleaned_links += 1 + + if cleaned_links > 0: RNS.log(f"Cleaned {cleaned_links} stale link{'s' if cleaned_links != 1 else ''}", RNS.LOG_DEBUG) + + def cleanup_link_temporary_resources(self, link): + if hasattr(link, "temporary_directories"): + for tmpdir in link.temporary_directories: + try: + tmpdir.cleanup() + RNS.log(f"Cleaned up {tmpdir.name}", RNS.LOG_DEBUG) + except Exception as e: RNS.log(f"Error while cleaning temporary directory: {e}", RNS.LOG_ERROR) + + link.temporary_directories = [] def remote_identified(self, link, identity): RNS.log(f"Peer identified as {link.get_remote_identity()} on {link}", RNS.LOG_DEBUG) @@ -2795,5 +3057,8 @@ DEFAULT_WORK_TEMPLATE = """{PAGE_CONTENT}""" DEFAULT_WORK_DOC_TEMPLATE = """{PAGE_CONTENT}""" +# Error state templates +DEFAULT_NO_IDENT_TEMPLATE = """>>No Identity\n\nThis page requires identification, and none was received.\n""" + # Fallback template FALLBACK_TEMPLATE = """{PAGE_CONTENT}""" \ No newline at end of file diff --git a/RNS/Utilities/rngit/server.py b/RNS/Utilities/rngit/server.py index 273f56b7..4b50dc55 100644 --- a/RNS/Utilities/rngit/server.py +++ b/RNS/Utilities/rngit/server.py @@ -1999,6 +1999,7 @@ class ReticulumGitNode(): self.active_links_lock = Lock() self.stats_lock = Lock() self.sync_lock = Lock() + self.perms_lock = Lock() self.stats_ignored = {} self.stats_push_ignored = {} self.node_name = "Anonymous Git Node" @@ -2507,6 +2508,22 @@ class ReticulumGitNode(): return permissions + def load_allowed_permissions(self, allowed_path): + allowed_input = "" + dynamic_perms = False + if os.path.isfile(allowed_path): + if os.access(allowed_path, os.X_OK): + allowed_result = subprocess.run([allowed_path], stdout=subprocess.PIPE) + allowed_input = allowed_result.stdout.decode("utf-8") + dynamic_perms = True + + else: + fh = open(allowed_path, "rb") + allowed_input = fh.read().decode("utf-8") + fh.close() + + return self.permissions_from_allowed_input(allowed_input), dynamic_perms + def load_repository_group(self, group_name, group_path): if not group_name in self.groups: self.groups[group_name] = { "path": group_path, "name": group_name, "repositories": {}, "dynamic_perms": False, "read": [], "write": [], "create": [], "stats": [], "release": [], @@ -2532,8 +2549,8 @@ class ReticulumGitNode(): RNS.log(f"Attempt to set group permissions for non-existing group {group_name}, aborting", RNS.LOG_WARNING) return - # Clear permissions before update - for perm in self.ALL_PERMS: self.groups[group_name][perm] = [] + new_permissions = {} + for perm in self.ALL_PERMS: new_permissions[perm] = [] # Apply permissions from allowed file if present group_path = self.groups[group_name]["path"] @@ -2541,22 +2558,14 @@ class ReticulumGitNode(): if os.path.isfile(allowed_path): RNS.log(f"Applying group permissions for {group_name} from {allowed_path}", RNS.LOG_DEBUG) try: - allowed_input = "" - if os.access(allowed_path, os.X_OK): - allowed_result = subprocess.run([allowed_path], stdout=subprocess.PIPE) - allowed_input = allowed_result.stdout.decode("utf-8") - self.groups[group_name]["dynamic_perms"] = True - - else: - fh = open(allowed_path, "rb") - allowed_input = fh.read().decode("utf-8") - fh.close() - - group_permissions = self.permissions_from_allowed_input(allowed_input) - for perm in group_permissions: self.groups[group_name][perm] = group_permissions[perm] + group_permissions, dynamic_perms = self.load_allowed_permissions(allowed_path) + for perm in self.ALL_PERMS: new_permissions[perm] = group_permissions[perm] + self.groups[group_name]["dynamic_perms"] = dynamic_perms except Exception as e: RNS.log(f"Could not load group permissions from {allowed_path}: {e}", RNS.LOG_ERROR) + else: self.groups[group_name]["dynamic_perms"] = False + # Apply permissions from config file if present if "access" in self.config: section = self.config["access"] @@ -2580,14 +2589,33 @@ class ReticulumGitNode(): if perm == self.PERM_PROPOSE: propose = True if perm == self.PERM_ADMIN: admin = True - if read and not target in self.groups[group_name]["read"]: self.groups[group_name]["read"].append(target) - if write and not target in self.groups[group_name]["write"]: self.groups[group_name]["write"].append(target) - if create and not target in self.groups[group_name]["create"]: self.groups[group_name]["create"].append(target) - if stats and not target in self.groups[group_name]["stats"]: self.groups[group_name]["stats"].append(target) - if release and not target in self.groups[group_name]["release"]: self.groups[group_name]["release"].append(target) - if interact and not target in self.groups[group_name]["interact"]: self.groups[group_name]["interact"].append(target) - if propose and not target in self.groups[group_name]["propose"]: self.groups[group_name]["propose"].append(target) - if admin and not target in self.groups[group_name]["admin"]: self.groups[group_name]["admin"].append(target) + if read and not target in new_permissions["read"]: new_permissions["read"].append(target) + if write and not target in new_permissions["write"]: new_permissions["write"].append(target) + if create and not target in new_permissions["create"]: new_permissions["create"].append(target) + if stats and not target in new_permissions["stats"]: new_permissions["stats"].append(target) + if release and not target in new_permissions["release"]: new_permissions["release"].append(target) + if interact and not target in new_permissions["interact"]: new_permissions["interact"].append(target) + if propose and not target in new_permissions["propose"]: new_permissions["propose"].append(target) + if admin and not target in new_permissions["admin"]: new_permissions["admin"].append(target) + + for perm in self.ALL_PERMS: self.groups[group_name][perm] = new_permissions[perm] + + def update_repository_permissions(self, group_name, repository_name): + if not group_name in self.groups: + RNS.log(f"Attempt to update permissions for non-existing group {group_name}, aborting", RNS.LOG_WARNING) + return + + if not repository_name in self.groups[group_name]["repositories"]: + RNS.log(f"Attempt to update permissions for non-existing repository {group_name}/{repository_name}, aborting", RNS.LOG_WARNING) + return + + repo = self.groups[group_name]["repositories"][repository_name] + allowed_path = repo["path"]+".allowed" + + try: + repo_permissions, dynamic_perms = self.load_allowed_permissions(allowed_path) + for perm in self.ALL_PERMS: repo[perm] = repo_permissions[perm] if perm in repo_permissions else [] + except Exception as e: RNS.log(f"Could not update repository permissions for {group_name}/{repository_name} from {allowed_path}: {e}", RNS.LOG_ERROR) def load_repository(self, group, path): if not group or not path: return False @@ -2601,27 +2629,15 @@ class ReticulumGitNode(): RNS.log(f"You can change it to a bare repository using \"git config --bool core.bare true\".", RNS.LOG_WARNING) else: - repository_name = os.path.basename(path) - allowed_path = f"{path}.allowed" - allowed_input = "" - dynamic_perms = False - if os.path.isfile(allowed_path): - if os.access(allowed_path, os.X_OK): - allowed_result = subprocess.run([allowed_path], stdout=subprocess.PIPE) - allowed_input = allowed_result.stdout.decode("utf-8") - dynamic_perms = True - - else: - fh = open(allowed_path, "rb") - allowed_input = fh.read().decode("utf-8") - fh.close() + repository_name = os.path.basename(path) + allowed_path = f"{path}.allowed" + repo_permissions, dynamic_perms = self.load_allowed_permissions(allowed_path) fork = self.__is_fork(path) mirror = self.__is_mirror(path) - p = self.permissions_from_allowed_input(allowed_input) group["repositories"][repository_name] = { "name": repository_name, "group": group_name, "path": path, "fork": fork, "mirror": mirror } - for perm in self.ALL_PERMS: group["repositories"][repository_name][perm] = p[perm] if perm in p else [] + for perm in self.ALL_PERMS: group["repositories"][repository_name][perm] = repo_permissions[perm] if perm in repo_permissions else [] return True @@ -4231,6 +4247,7 @@ class ReticulumGitNode(): return self.RES_REMOTE_FAIL.to_bytes(1, "big") + b"Remote error" def _work_complete(self, work_path, data, remote_identity): + group_name, repository_name = self.parse_request_repository_path(data[self.IDX_REPOSITORY]) doc_id = data.get("doc_id") if doc_id is None: return self.RES_INVALID_REQ.to_bytes(1, "big") + b"No document ID specified" @@ -4246,7 +4263,9 @@ class ReticulumGitNode(): doc = self._work_load_document(root_path) if not doc: return self.RES_REMOTE_FAIL.to_bytes(1, "big") + b"Error loading document" - if doc.get("meta", {}).get("author") != remote_identity.hash: return self.RES_DISALLOWED.to_bytes(1, "big") + b"No access, not author" + is_author = doc.get("meta", {}).get("author") == remote_identity.hash + admin_access = self.resolve_doc_permission(remote_identity, group_name, repository_name, doc_id, self.PERM_ADMIN) + if not is_author and not admin_access: return self.RES_DISALLOWED.to_bytes(1, "big") + b"Not allowed" try: completed_dir = os.path.join(completed_base, str(doc_id)) @@ -4260,26 +4279,35 @@ class ReticulumGitNode(): return self.RES_REMOTE_FAIL.to_bytes(1, "big") + b"Remote error" def _work_activate(self, work_path, data, remote_identity): + group_name, repository_name = self.parse_request_repository_path(data[self.IDX_REPOSITORY]) doc_id = data.get("doc_id") if doc_id is None: return self.RES_INVALID_REQ.to_bytes(1, "big") + b"No document ID specified" try: doc_id = int(doc_id) except: return self.RES_INVALID_REQ.to_bytes(1, "big") + b"Invalid document ID" - completed_dir = os.path.join(work_path, "completed", str(doc_id)) active_base = os.path.join(work_path, "active") - if not os.path.isdir(completed_dir): return self.RES_NOT_FOUND.to_bytes(1, "big") + b"Document not found" + doc_dir = None + for scope in ["completed", "proposed"]: + d = os.path.join(work_path, scope, str(doc_id)) + if os.path.isdir(d): + doc_dir = d + break + + if not doc_dir: return self.RES_NOT_FOUND.to_bytes(1, "big") + b"Document not found" - root_path = os.path.join(completed_dir, "root") + root_path = os.path.join(doc_dir, "root") doc = self._work_load_document(root_path) if not doc: return self.RES_REMOTE_FAIL.to_bytes(1, "big") + b"Error loading document" - if doc.get("meta", {}).get("author") != remote_identity.hash: return self.RES_DISALLOWED.to_bytes(1, "big") + b"No access, not author" + is_author = doc.get("meta", {}).get("author") == remote_identity.hash + admin_access = self.resolve_doc_permission(remote_identity, group_name, repository_name, doc_id, self.PERM_ADMIN) + if not is_author and not admin_access: return self.RES_DISALLOWED.to_bytes(1, "big") + b"Not allowed" try: active_dir = os.path.join(active_base, str(doc_id)) - shutil.move(completed_dir, active_dir) + shutil.move(doc_dir, active_dir) RNS.log(f"Activated work document {doc_id} by {RNS.prettyhexrep(remote_identity.hash)}", RNS.LOG_VERBOSE) return b"\x00" + mp.packb({"id": doc_id, "scope": "active"}) @@ -4505,10 +4533,17 @@ class ReticulumGitNode(): try: group_path = self.groups[group_name]["path"] allowed_path = group_path + ".allowed" + + if os.access(allowed_path, os.X_OK): return self.RES_DISALLOWED.to_bytes(1, "big") + b"Executable permission resolvers can only be modified node-side" + tmp_path = allowed_path + ".tmp" with open(tmp_path, "w", encoding="utf-8") as f: f.write(content) os.rename(tmp_path, allowed_path) + with self.perms_lock: + try: self.update_group_permissions(group_name) + except Exception as e: RNS.log(f"Error while refreshing permissions for group {group_name}: {e}", RNS.LOG_ERROR) + RNS.log(f"Permissions for group {group_name} updated by {RNS.prettyhexrep(remote_identity.hash)}", RNS.LOG_VERBOSE) return b"\x00" @@ -4580,10 +4615,17 @@ class ReticulumGitNode(): try: repo_path = self.groups[group_name]["repositories"][repository_name]["path"] allowed_path = repo_path + ".allowed" + + if os.access(allowed_path, os.X_OK): return self.RES_DISALLOWED.to_bytes(1, "big") + b"Executable permission resolvers can only be modified node-side" + tmp_path = allowed_path + ".tmp" with open(tmp_path, "w", encoding="utf-8") as f: f.write(content) os.rename(tmp_path, allowed_path) + with self.perms_lock: + try: self.update_repository_permissions(group_name, repository_name) + except Exception as e: RNS.log(f"Error while refreshing permissions for repository {group_name}/{repository_name}: {e}", RNS.LOG_ERROR) + RNS.log(f"Permissions for repository {group_name}/{repository_name} updated by {RNS.prettyhexrep(remote_identity.hash)}", RNS.LOG_VERBOSE) return b"\x00" @@ -4897,6 +4939,11 @@ announce_interval = 360 # blocked_identities = d31aeea49873006f13b3415520666a4e +# To make it easier to handle scrapers, crawlers, slopware +# and other annoyances, you can block unidentified peers by +# adding the null_ident hash to to blocked identities. + +# blocked_identities = d7db22f63b453c23bb0688dde565b7c1 [repositories] @@ -4996,14 +5043,26 @@ internal = rw:9710b86ba12c42d1d8f30f74fe509286 # serve_nomadnet = no -# It is possible to disable Nerd Font icons and instead +# It is possible to disable Nerd Font icons and instead # use simpler (but more compatible) unicode icons. # unicode_icons = yes +# You can configure whether the page server should try +# to convert media files to WebP on the fly, for serving +# to nomadnet clients. Enabled by default, but will +# require an available encoding backend installed on +# your system. Supported backends utilities are "magick", +# "convert", "gm", "ffmpeg" and "avconv". If any one is +# installed, rngit will auto-detect and use it, but you +# can force a specific backend with the environment +# variable RNGIT_MEDIA_BACKEND. + +# media_conversion = yes + [logging] -# Valid log levels are 0 through 7: +# Valid log levels are 0 through 8: # 0: Log only critical information # 1: Log errors and lower log levels # 2: Log warnings and lower log levels @@ -5011,7 +5070,8 @@ internal = rw:9710b86ba12c42d1d8f30f74fe509286 # 4: Log info and lower (this is the default) # 5: Verbose logging # 6: Debug logging -# 7: Extreme logging +# 7: Pathing logging +# 8: Extreme logging loglevel = 4 diff --git a/RNS/Utilities/rnsd.py b/RNS/Utilities/rnsd.py index 515fffba..4e4e5ea3 100755 --- a/RNS/Utilities/rnsd.py +++ b/RNS/Utilities/rnsd.py @@ -215,6 +215,14 @@ instance_name = default # required_discovery_value = 14 +# You can disable allowing interfaces to be attached, de- +# tached or reloaded via rnstatus, for example if running +# on a shared system where users with normal RPC access +# should not be allowed to control interface states. + +# enable_interface_management = no + + # You can configure Reticulum to panic and forcibly close # if an unrecoverable interface error occurs, such as the # hardware device for an interface disappearing. This is diff --git a/RNS/Utilities/rnstatus.py b/RNS/Utilities/rnstatus.py index 04754dfa..c69b62bb 100644 --- a/RNS/Utilities/rnstatus.py +++ b/RNS/Utilities/rnstatus.py @@ -159,7 +159,8 @@ def get_remote_status(destination_hash, include_lstats, include_profiling, ident def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=False, astats=False, pstats=False, lstats=False, sorting=None, sort_reverse=False, remote=None, management_identity=None, must_exit=True, rns_instance=None, traffic_totals=False, discovered_interfaces=False, config_entries=False, burst_filter=False, blocked_ips=False, - queue_stats=False, pps=False, profiling=False, remote_timeout=RNS.Transport.PATH_REQUEST_TIMEOUT): + queue_stats=False, pps=False, profiling=False, remote_timeout=RNS.Transport.PATH_REQUEST_TIMEOUT, + attach=None, detach=None, reload=None, show_stale=False, show_unknown=False): if remote: require_shared = False else: require_shared = True @@ -176,6 +177,37 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= if must_exit: exit(1) else: return + if attach: + result = reticulum.attach_interface(attach) + if result == True: print(f"Interface {attach} was attached") + elif result == False: print(f"Could not attach interface {attach}") + elif result == None: print(f"The interface {attach} does not exist") + else: print(f"Unknown error while attaching interface {attach}") + + if result == True: exit(0) + else: exit(1) + + if detach: + result = reticulum.detach_interface(detach) + if result == True: print(f"Interface {detach} was detached") + elif result == False: print(f"Could not detach interface {detach}") + elif result == None: print(f"The interface {detach} does not exist") + else: print(f"Unknown error while detaching interface {detach}") + + if result == True: exit(0) + else: exit(1) + + if reload: + result = reticulum.reload_interface(reload) + if result == True: print(f"Interface {reload} was reloaded") + elif result == False: print(f"Could not reload interface {reload}") + elif result == None: print(f"The interface {reload} does not exist") + else: print(f"Unknown error while reloading interface {reload}") + + if result == True: exit(0) + else: exit(1) + + link_count = None active_link_count = None stats = None @@ -211,12 +243,17 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= name = i["name"] if_type = i["type"] status = i["status"] + has_impl_info = "impl_name" in i and "version" in i and i["impl_name"] and i["version"] + impl_str = f"{i['impl_name']} {i['version']}" if has_impl_info else "Unknown" if status == "available": status_display = "Available" elif status == "unknown": status_display = "Unknown" elif status == "stale": status_display = "Stale" else: status_display = status + if status == "stale" and not show_stale: continue + if not has_impl_info and not show_unknown: continue + now = time.time() dago = now-i["discovered"] hago = now-i["last_heard"] @@ -247,6 +284,7 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= print(f"Name : {name}") print(f"Type : {if_type}") + print(f"Stack : {impl_str}") print(f"Status : {status_display}") print(f"Transport : {transport_str}") print(f"Distance : {i['hops']} hop{'' if i['hops'] == 1 else 's'}") @@ -271,12 +309,15 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= except Exception as e: pass else: - print(f"{'Name':<25} {'Type':<12} {'Status':<12} {'Last Heard':<12} {'Value':<8} {'Location':<15}") - print("-" * 89) + print(f"{'Name':<25} {'Type':<10} {'Status':<10} {'Last Heard':<12} {'Value':<7} {'Running':<16} {'Location':<15}") + print("-" * 110) for i in filtered_ifs: try: name = i["name"][:24] + "…" if len(i["name"]) > 24 else i["name"] + has_impl_info = "impl_name" in i and "version" in i and i["impl_name"] and i["version"] + impl_str = f"{i['impl_name']} {i['version']}" if has_impl_info else "Unknown" + if len(impl_str) > 16: impl_str = impl_str[:15]+"…" if_type = i["type"].replace("Interface", "") @@ -285,6 +326,9 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= elif status == "unknown": status_display = "? Unknown" elif status == "stale": status_display = "× Stale" else: status_display = status + + if status == "stale" and not show_stale: continue + if not has_impl_info and not show_unknown: continue now = time.time() last_heard = i["last_heard"] @@ -309,7 +353,7 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= location = f"{lat}, {lon}" else: location = "N/A" - print(f"{name:<25} {if_type:<12} {status_display:<12} {last_heard_display:<12} {value:<8} {location:<15}") + print(f"{name:<25} {if_type:<10} {status_display:<12} {last_heard_display:<12} {value:<7} {impl_str:<16} {location:<15}") except Exception as e: pass @@ -832,6 +876,10 @@ def main(must_exit=True, rns_instance=None): parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str) parser.add_argument("--version", action="version", version="rnstatus {version}".format(version=__version__)) + parser.add_argument("--attach", action="store", metavar="name", help="Attach interface by name", default=None, type=str) + parser.add_argument("--detach", action="store", metavar="name", help="Detach interface by name", default=None, type=str) + parser.add_argument("--reload", action="store", metavar="name", help="Reload interface by name", default=None, type=str) + parser.add_argument("-a", "--all", action="store_true", help="show all interfaces", default=False) parser.add_argument("-A", "--announce-stats", action="store_true", help="show announce stats", default=False) parser.add_argument("-P", "--pr-stats", action="store_true", help="show path request stats", default=False) @@ -850,6 +898,8 @@ def main(must_exit=True, rns_instance=None): parser.add_argument("-w", action="store", metavar="seconds", type=float, help="timeout before giving up on remote queries", default=RNS.Transport.PATH_REQUEST_TIMEOUT) parser.add_argument("-d", "--discovered", action="store_true", help="list discovered interfaces", default=False) parser.add_argument("-D", action="store_true", help="show details and config entries for discovered interfaces", default=False) + parser.add_argument("--show-stale", action="store_true", help="show stale discovery entries", default=False) + parser.add_argument("--show-unknown", action="store_true", help="show discovery entries without version info", default=False) parser.add_argument("-m", "--monitor", action="store_true", help="continuously monitor status", default=False) parser.add_argument("-I", "--monitor-interval", action="store", metavar="seconds", type=float, help="refresh interval for monitor mode (default: 1)", default=1.0) parser.add_argument('-v', '--verbose', action='count', default=0) @@ -880,7 +930,8 @@ def main(must_exit=True, rns_instance=None): astats=args.announce_stats, pstats=args.pr_stats, lstats=args.link_stats, sorting=args.sort, sort_reverse=args.reverse, remote=args.R, management_identity=args.i, remote_timeout=args.w, must_exit=False, rns_instance=reticulum, traffic_totals=args.totals, discovered_interfaces=args.discovered, config_entries=args.D, burst_filter=args.burst, - blocked_ips=args.blocked_ips, queue_stats=args.queues, pps=args.pps, profiling=args.profiling) + blocked_ips=args.blocked_ips, queue_stats=args.queues, pps=args.pps, profiling=args.profiling, + show_stale=args.show_stale, show_unknown=args.show_unknown) finally: sys.stdout = old_stdout @@ -898,7 +949,8 @@ def main(must_exit=True, rns_instance=None): astats=args.announce_stats, pstats=args.pr_stats, lstats=args.link_stats, sorting=args.sort, sort_reverse=args.reverse, remote=args.R, management_identity=args.i, remote_timeout=args.w, must_exit=must_exit, rns_instance=rns_instance, traffic_totals=args.totals, discovered_interfaces=args.discovered, config_entries=args.D, burst_filter=args.burst, - blocked_ips=args.blocked_ips, queue_stats=args.queues, pps=args.pps, profiling=args.profiling) + blocked_ips=args.blocked_ips, queue_stats=args.queues, pps=args.pps, profiling=args.profiling, + attach=args.attach, detach=args.detach, reload=args.reload, show_stale=args.show_stale, show_unknown=args.show_unknown) except KeyboardInterrupt: print("") diff --git a/RNS/_version.py b/RNS/_version.py index 0f228f25..8c118e61 100644 --- a/RNS/_version.py +++ b/RNS/_version.py @@ -1 +1 @@ -__version__ = "1.5.1" +__version__ = "1.5.5" diff --git a/Roadmap.md b/Roadmap.md deleted file mode 100644 index 5689e309..00000000 --- a/Roadmap.md +++ /dev/null @@ -1,94 +0,0 @@ -# Reticulum Development Roadmap -This document outlines the currently established development roadmap for Reticulum. - -1. [Currently Active Work Areas](#currently-active-work-areas) -2. [Primary Efforts](#primary-efforts) - - [Comprehensibility](#comprehensibility) - - [Universality](#universality) - - [Functionality](#functionality) - - [Usability & Utility](#usability--utility) - - [Interfaceability](#interfaceability) -3. [Auxillary Efforts](#auxillary-efforts) -4. [Release History](#release-history) - -## Currently Active Work Areas -For each release cycle of Reticulum, improvements and additions from the five [Primary Efforts](#primary-efforts) are selected as active work areas, and can be expected to be included in the upcoming releases within that cycle. While not entirely set in stone for each release cycle, they serve as a pointer of what to expect in the near future. - -## Primary Efforts -The development path for Reticulum is currently laid out in five distinct areas: *Comprehensibility*, *Universality*, *Functionality*, *Usability & Utility* and *Interfaceability*. Conceptualising the development of Reticulum into these areas serves to advance the implementation and work towards the Foundational Goals & Values of Reticulum. - -### Comprehensibility -These efforts are aimed at improving the ease of which Reticulum is understood, and lowering the barrier to entry for people who wish to start building systems on Reticulum. - -- Improving [the manual](https://markqvist.github.io/Reticulum/manual/) with tutorials specifically for beginners -- Updating the documentation to reflect recent changes and improvements - - Update descriptions of protocol mechanics - - Update announce description - - Add in-depth explanation of the IFAC system - - Software - - Update software descriptions and screenshots - - Communications hardware section - - Add information about RNode external displays. - - Possibly add other relevant types here as well. - - Setup *Best Practices For...* / *Installation Examples* section. - - Home or office (example) - - Vehicles (example) - - No-grid/solar/remote sites (example) - -### Universality -These efforts seek to broaden the universality of the Reticulum software and hardware ecosystem by continously diversifying platform support, and by improving the overall availability and ease of deployment of the Reticulum stack. - -- Create a standalone RNS Daemon app for Android -- A lightweight and portable C implementation for microcontrollers, µRNS -- A portable, high-performance Reticulum implementation in C/C++, see [#21](https://github.com/markqvist/Reticulum/discussions/21) -- Bindings for other programming languages - -### Functionality -These efforts aim to expand and improve the core functionality and reliability of Reticulum. - -- Add interface hot-plug and live up/down control to running instances -- Add automatic retries to all use cases of the `Request` API -- Network-wide path balancing -- Distributed Destination Naming System -- Globally routable multicast -- Destination proxying -- [Metric-based path selection and multiple paths](https://github.com/markqvist/Reticulum/discussions/86) - -### Usability & Utility -These efforts seek to make Reticulum easier to use and operate, and to expand the utility of the stack on deployed systems. - -- Easy way to share interface configurations, see [#19](https://github.com/markqvist/Reticulum/discussions/19) -- Transit traffic display in `rnstatus` -- `rnsconfig` utility - -### Interfaceability -These efforts aim to expand the types of physical and virtual interfaces that Reticulum can natively use to transport data. - -- Plain ESP32 devices (ESP-Now, WiFi, Bluetooth, etc.) -- More LoRa transceivers -- AT-compatible modems -- Filesystem interface -- Direct SDR Support -- Optical mediums -- IR Transceivers -- AWDL / OWL -- HF Modems -- GNU Radio -- CAN-bus -- Raw SPI -- Raw i²c -- MQTT -- XBee -- Tor - -## Auxillary Efforts -The Reticulum ecosystem is enriched by several other software and hardware projects, and the support and improvement of these, in symbiosis with the core Reticulum project helps expand the reach and utility of Reticulum itself. - -This section lists, in no particular order, various important efforts that would be beneficial to the goals of Reticulum. - -- The [RNode](https://unsigned.io/rnode/) project - - [x] Create a WebUSB-based bootstrapping utility, and integrate this directly into the [RNode Bootstrap Console](#), both on-device, and on an Internet-reachable copy. This will make it much easier to create new RNodes for average users. - -## Release History - -Please see the [Changelog](./Changelog.md) for a complete release history and changelog of Reticulum. \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..dae1b7f3 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Reporting Security Issues + +It goes without saying: If you have discovered a security issue in Reticulum or any related project, please report it responsibly to the maintainer over LXMF at `<8dd57a738226809646089335a6b03695>`. If you wish to remain anonymous, please create a disposable identity to send from, and notify us of any such wishes. + +If you are not able to use LXMF, you can send an email to the address currently posted on the maintainer's profile on this site. diff --git a/This Is Not a Teahouse.md b/This Is Not a Teahouse.md index 754769be..d56a00b6 100644 --- a/This Is Not a Teahouse.md +++ b/This Is Not a Teahouse.md @@ -2,7 +2,7 @@ Recently, and mostly from people who I've never seen before, the opinions about - The decision to no longer mirror release notes on GitHub. - Some people feeling there were too many "barriers to entry" to joining RNS development. -- The project not really being "open source" because random strangers couldn't just "contribute". +- The project not really being "[open source](https://reticulum.network/manual/brandolinis.html#open-source-means-open-source)" because random strangers couldn't just "contribute". Joakim posted some very relevant observations about how Reticulum operates, along with the following quote: @@ -10,7 +10,7 @@ Joakim posted some very relevant observations about how Reticulum operates, alon That E. F. Schumacher quote perfectly illustrates the ontological schism that makes it so tiresome to deal with stuff like this. -There is, in this day and age, between different people, widely different base conceptual integrations of what "open source" means. For many people, "open source" has become synonymous **not** with skilled people working together in a coordinated and careful way on complex engineering challenges, but a sort of growth- and attention-focused "free-for-all" *behavioral* codex that must be followed above all else; a *social* modus operandi of fake inclusivity where everyone "should have their voice heard", and adherence to that specific process is weighed much higher than the final results. +There is, in this day and age, between different people, widely different base conceptual integrations of what "open source" means. For many people, "open source" has become synonymous **not** with skilled people working together in a coordinated and careful way on complex engineering challenges, but a sort of growth- and attention-focused "free-for-all" *behavioral* codex that must be followed above all else; a *social* modus operandi of fake inclusivity where everyone "should have their voice heard", and adherence to that specific *process* is weighed much higher than the final results. I do not subscribe to, and consequently do not operate the Reticulum project under *any* versions of that idea. @@ -28,7 +28,7 @@ I do not subscribe to, and consequently do not operate the Reticulum project und Can you imagine how much time that wasted? Can you imagine what we could have accomplished with that time instead? -The only thing that this creates is *noise* and confusion. Clogging up the mental and physical workspaces, of people who are actually investing time and effort on the project with stuff like that is objectively just taking time that could have been used on development, and replacing it with *nothing*. +The only thing that this creates is *noise* and confusion. Clogging up the mental and physical workspaces, of people who are actually investing time and effort on the project, with stuff like that is objectively just taking time that could have been used on development, and replacing it with *nothing*. I was receiving *actual* bug reports, pull requests, proper technical investigations and patches via methods outside GitHub and "public" internet-based channels *way* before GitHub interaction and similar was closed down. That was were almost *all* of the real contributions were coming from, anyway. Apparently, and not unsurprisingly, the people who has invested the time and effort to understand Reticulum also prefer to collaborate in this way. Since leaving the GitHub madhouse behind, the signal-to-noise ratio has **significantly** increased. @@ -46,7 +46,7 @@ When this pattern repeats, over and over, the only sensible, measured and constr So, now it's your turn. Go look at the diffs for the last six months. What does it look like I have been doing? -But I will be damned straight with you all, and say that part of that solution is **absolutely** to erect barriers to entry. You can fucking bet your arse on that. I don't want opinionated man-babies running around in my living-room at 3am. I don't want to clean up the floor after a wannabe "dev-ops stars" with LLMs and a peripheral case of influencitis has puked all over the office. +But I will be damned straight with you all, and say that part of that solution is **absolutely** to erect barriers to entry. You can fucking bet your arse on that. I don't want opinionated man-babies running around in my living-room at 3am. I don't want to clean up the floor after a wannabe "dev-ops star" with LLMs and a peripheral case of influencitis has puked all over the office. - If you want to join the fun of changing core networking code that thousands of people rely on for communication daily, you better know what the fuck you're doing. diff --git a/docs/history/2026_09_18_Yes_I_am_Angry.md b/docs/history/2026_09_18_Yes_I_am_Angry.md new file mode 100644 index 00000000..699ac182 --- /dev/null +++ b/docs/history/2026_09_18_Yes_I_am_Angry.md @@ -0,0 +1,339 @@ +# Yes, I am Angry + +Polite, but deeply malicious bullshit is a much worse evil than the coarse variant, so you will have to excuse my bluntness here. + +Unfortunately, the only way to respond, as a normal, healthy human being, to something so astronomically tasteless and disgraceful as this, is not in kind, but in honest outrage, modulated to some degree with sarcasm and humor (the dark variant, yes). + +Because *this* shit, this *is* outrageous. + +The man that produced the "article" in question here is either so disposessed of intelligence that his head is teetering on the brink of collapsing into a singularity, or he is deeply malicious. + +If any rational explanation can produce an alternative, I am all ears. + +**To the footsoldiers of the "cause" the article represents** + +Let's get this show on. Let's see the barrage of new smear pieces you can prompt forth from the fuel I provide you here. It'll fit straight into your theater production, so: Be my fucking guest, and dig your own hole of delusion, mistrust and ridicule even deeper than it already is. I can then hurl it right back at you, and we can all have a crap-fight till the end of days. *Or* we could take responsibility and ownership for our words and actions, and actually build something together. Ball's in your court. + +**To anyone else** + +Consider this a paranthetical, sarcastic (and for me, cathartic) aside in the whole of the corpus of writings I have published, and weigh it in the context of the rest of those 200,000 words or so, together with the frustration and exhaustion that inevitably entails from dealing with this same fabricated campaign and its regurgitated nonsense for *years* on end, while trying to do constructive and helpful work; and not expecting anything else than basic decency in return. + +I am no angel, not perfect, flawed in many ways, but I certainly ain't afraid to show that I am a real human being, with the capacity for anger, and that in this case, the anger is fed by the most bitter form of disappointment and sadness in what people will stoop to for influence and attention. + +[This is the article in question](https://gaggl.com/blogs/2026-09-05-enclosure-by-good-intentions/) + +[This is the polite, measured analysis of the *generalized* phenomenon, all 18,000 words of it](https://reticulum.network/manual/brandolinis.html) + +And here is a very short, but central point from that analysis: + +> In whole, this is the description of three fronts of the same operation: +> +> * The license attack and other urgency-engineered narratives are the *cover*: They supply +> the ideological justification and battering ram for treating the reference as illegitimate, +> and needing replacement. +> * The ports are the *inventory*: they supply the “replacement” material that the narrative +> claims the ecosystem needs. +> * The takeover narrative is the *objective function*: the repeated, persistent, escalating claim that +> the reference should be replaced, and that the speakers themself are the natural heirs. + +--- + +*This*, right here, is the real, human and honest response. And the only sane one there could ever be, lest madness be allowed to descend wholly. + +While this is *written* as a response to you, Leo Gaggl, you absolute degenerate piece of fecal matter, it is really a response to the phenomenon *as a whole*. + +I chose your article because it is such a complete and rich example of the madness. What I attack here is *conduct*. + +Leo, according to his own evident preference, is the actor on the theatre stage, and I will treat him as such, in the play that follows. + +--- + +> So when Mark Qvist, the person behind the [Reticulum](https://gaggl.com/blogs/2026-02-25-lpwan-meshes-reticulum-deep-dive/) mesh networking stack + +Color me surprised, the link to "Reticulum" doesn't even point to the repo, but to *another* one of your sloporated "articles". + +Don't wanna accidentially lead users to anywhere they could discover the truth about things now, would we? Like commit histories, the *actual* Reticulum community, that kind of stuff. Nah, nah... + +> ... replaced its MIT licence with a custom one built to keep the project out of corporate AI training sets and out of weapons systems + +Which happened 18 months ago. *Fuuuunny* timing bringing it up again now, right where it's [mighty fucking convenient](https://reticulum.network/manual/brandolinis.html#a-persistent-but-fragile-triad) for your slop-coding license-violating friends, don't you think? + +Interesting you don't bring up *any* of the extensive argumentation made against the same old points you recycle here, but act as they simply never existed. Or maybe you just chose to completely ignore them in the service of your God-given mission? + +> Reticulum is now marked non-free by Debian + +Which is [excellent](https://reticulum.network/manual/brandolinis.html#the-distribution-argument), since debian users will not have to use old, and potentially outdated versions of a package that updates *fast* everytime it is required. + +And "now"? Weasel wording. + +> kept out of the main F-Droid repository + +RNS? In the F-Droid repository? How would that even work? People install the base stack as an *app* and run it... how? Are we going to bundle a command line or `systemd` with that? Do you have any idea about how software actually works? + +If people want to do that, open Termux and type `pip install rns`. Done. Has been possible and documented since the dawn of the project. + +All actual *apps* that use Reticulum are distributed as APKs, ready to install and download, distribute offline, fetch from their websites, over Reticulum itself, or whatever platform they prefer. Commercially or for free. That's the point. + +> It cannot be combined with GPL-licensed code + +[Cry me a river](https://reticulum.network/manual/brandolinis.html#on-freedom). Not my fault that people choose to use viral licenses that absolutely must subsume everything and their aunt under their own restrictive terms. + +> It is not eligible for most open-source grant funding. + +Exactly, and I specifically rejected that, several times, to keep the license right and avoid political takeover. That's 50.000€ I said no to, right there, while I barely had enough to make it three months into the future. Because I value integrity and *real* sustainability a lot higher. + +Do *you* have anything to show for it, in that regard? Who's footing your pay-check? A varied community of people from all walks of life who use the things you created? No? Didn't think so. I wonder who, then. + +> And the clause that triggered all of this is very likely unenforceable. + +"Very likely" is very likely a lot of handwaving, Leo. It's certainly not an argument. [This is](https://reticulum.network/manual/brandolinis.html#what-the-reticulum-license-is). + +> As one Debian developer put it in the project’s own discussion thread, people who build harmful systems are not going to be stopped by a term they were always going to ignore. + +It turns out [that most do](https://reticulum.network/manual/brandolinis.html#the-prediction-and-what-happened), because of a thing called "the law". + +Or are you proposing we live in a state of complete and utter anarchy already? Or maybe that your cult is simply above the law? + +> The moment you add a “not for harm” or “not for AI” condition, you have left open source behind + +Strike up the organ, start the hymns. + +> The Open Source Definition rules out licences that discriminate against people or groups, or against fields of endeavour + +[Erratum](https://reticulum.network/manual/brandolinis.html#open-source-means-open-source): *Your* "open source" religion, not "The Open Source Definition" (Capitals Of Authority, bravo). + +Yes, let's not discriminate against people, **BY FUCKING MURDERING THEM WITH DRONES**. Time for a party Leo! + +Beauuuutiful way to hide [the true nonsense](https://reticulum.network/manual/brandolinis.html#what-the-argument-is-actually-doing) of the "fields of endeavour" by slyly insinuating *I* am being discriminatory. + +Side-note: The overall patronizing, better-than-thy and fakely knowledgable tone is almost hilarious, if it wasn't so malicious. + +> The tool was already on the shelf + +Oh for Christ's sake, this one [again](https://reticulum.network/manual/brandolinis.html#recycled-wine-fermenting)... + +> Kaonic tactical mesh radios are sold for military command and control, drone and autonomous-systems networking, and operation in “austere, contested environments”, and which has since been selected for NATO’s DIANA defence-innovation accelerator. It is MIT-licensed, it is an independent implementation of a protocol that is itself public domain, and its repository predates Qvist’s harm clause by nine months. + +Those fuckers came to me and presented themselves as wanting to create a rust port for the good of the ecosystem, the world and the community. That was a blatant lie and front for their actual goal of acquiring my goodwill and expertise so they could quickly create a shallow clone, hardfork it with their own sloppy "Post-Quantum" crypto, and get big money from the military. They deliberately lied and manipulated to extract from a whole community and someone they believed to be a naive, vulnerable developer. + +Why do you think a non-harm clause is needed? Their implementation is still not *working*, by the way, and has provided **nothing** to the community or world at large. + +I cut ties with those bastards when I found out what their end-game was, but not until I had spent every ounce of energy I had slowing them down as much as humanly possible, while *I was still working on the actual Reticulum implementation and providing updates to users, managing a community, and living on next to nothing in a camper*. + +Holy fuck I hate people like you Leo, you willfully ignorant, destructive, spoiled piece of shit. + +> His fix trades a door nobody has worked out how to close for the loss of every distribution channel + +Every distribution channel that [we never used, and never needed](https://reticulum.network/manual/brandolinis.html#the-distribution-argument)? I haven't seen PyPi acting up about our apparently infuriating conduct yet. + +Moot point, even if they do, since we can distribute over Reticulum just fine. With full cryptographic authentication, and no centralized infrastructure or PKI required. Also, no governance required. *That's* resilience. + +> and every downstream collaborator who needs a known-good licence. + +We are definitely not short of downstream collaborators currently, so no thanks, you don't have much to sell me there. + +> You pay the full price in distribution and collaboration + +The quality of collaboration has gone up *significantly* since that decision. Most of the wannabes stay away and sob in their Stallman handkerchiefs, while we keep working, dilligently as always. Great success. + +(Sorry Stallman, I love you) + +Reticulum is available everywhere. It is one of the leanest, most dependency free software packages there is, and it ships an entire networking stack, a plethora of management utilities, a device flashing utility, a full GitHub replacement running over Reticulum, remote shell utilities, and supports a whole ecosystem of application-layer protocols and user-facing applications, including messaging (LXMF), voice (LXST), chat (RRC), content hosting and browsing (nomadnet), and many others. + +*In a cross-platform, portable wheel of 537 kilobytes* that installs or embeds on every platform known to man. Drop it on a floppy, baby. + +The delusions run so deep here I cannot even begin to fathom it. + +> and you get an AI-training restriction a determined actor routes around in an afternoon. + +In reality, of the 10 sampled language models (both proprietary and open-weights) that were tested for traces of Reticulum source material, *all* stopped training on the Reticulum source after the license change. + +Turns out, *it worked*, Leo. + +Did *you* check? No you didn't, handwaving and inventions again. + +> A written answer to “what happens when the maintainer walks away”, because for Reticulum that stopped being hypothetical in December 2025. + +Did you check the [commit logs](https://github.com/markqvist/Reticulum/commits/) you dimwit? No, you just randomly rolled around in the personal puddle of phantasmogoria you constructed from wishful thinking. + +Have you seen what I have produced in those ten months? I'd wager it's a lot more than you, you lazy fuck, not even doing the most basic fact-checking of your smear-job propaganda pieces. + +Try that on for a "written answer". + +> There is now a Reticulum_CE, a “community edition” fork that exists mainly to carry a redistributable licence. + +What psychosis are you getting these from? [Reticulum_CE](https://github.com/Reticulum-Community/Reticulum_CE) is published under the Reticulum License. Did you read their repo? No, you did not: + +*"This is a community maintained fork of the Reticulum Network Stack and is intended as a public forum for discussion and issue reporting, as well as a repository to collect community enhancements to RNS."* + +> There is RetiNet, an AGPL fork of the Python stack. + +Which has been [defunct and abandoned for 8 months](https://codeberg.org/SkyGuy/RetiNet). Are you not equipped with visual perception or basic literacy? + +> There are side-loaded F-Droid repositories so people can install the apps at all. + +What nonsense is this? You are literally so horny to paint a picture of a dead system that you have to assume people cannot think for two seconds straight? + +There has never been a point in time where people could not install Reticulum-based apps on Android. These have always, intentionally, been distributed as *re-distributable* APK files so people could share them offline. Sideband can host and share it's own APK. This is the point, Archimedes. + +The F-droid repository was made as service to users by a volunteer in the *real* Reticulum community (not your abhorrent confabulation of what it is) who *has never once objected to the license and project directions*, and who just wanted to help make things easier! + +Don't use them as ammunition in your perverse fantasies! + +> Every one of those is real maintenance work, done by volunteers, spent entirely on the problem of being allowed to share the software. + +A copy of my repo, then pasting my (Reticulum Licensed) work into four files, then abandoning the project is not "real maintenance work". + +What I have been doing, for over a decade, is real maintenance work. + +> four independent teams have rebuilt Reticulum from scratch in Rust. + +Those [have not "rebuild"](https://reticulum.network/manual/brandolinis.html#copyright-the-two-legal-layers) anything ["from scratch"](https://reticulum.network/manual/brandolinis.html#the-clean-room-delusion). + +They are feeding the source code of RNS directly into an LLM, running automated software loops, and copying it, blatantly, bit for bit, without any modicum of creative input, work or understanding. + +Such a connoisseur of the commons you are. + +> The people rebuilding the project to keep it alive + +The project is already alive, and has been for a decade. You are lying so hard that it's fucking raining. + +Those people, are in their own words, "Killing Reticulum" (quote, Lew Palm, "author" of "Leviculum"), so they can appropriate it for their own profit and control. + +> The two that put enclosure resistance first, Leviculum and the rsReticulum stack behind Ratspeak, both chose AGPLv3. + +And all of those are [void and null](https://reticulum.network/manual/brandolinis.html#void-grants-legal-foundations-of-machine-generated-code), because what they *really* chose is **copyright violation**, and complete disrespect ([as is now becoming tradition](https://reticulum.network/manual/brandolinis.html#licensing-analysis)) for open source development practices, attribution and basic decency. + +> Underneath the licence choice sits a harder problem, and it is the one this site keeps coming back to: a system can be decentralised in its architecture and completely centralised in who decides things. + +Oooooh... Tension. Drama. Tell me more, let's have the juicy details, huh? Outrage incoming, I can feel it! Ramp up your audience like a good boy, Leo! + +The only thing that keeps coming back here is nonsense. + +The decisions follow those responsible, over years, and the actual work. Not cry-babies like you. Get used to it. + +> Relicensing a codebase other people contributed to, under MIT terms, with a single unilateral commit, is itself a small act of enclosure. + +I am responsible for over 98% of commits in that repository. Not a single one of the other contributors disagreed to the license decision. + +But your ideology runs so deep now, *that we cannot ourselves decide how we license our own software*? Yes, let's consider for a moment **who the fucking dictator is here**... + +It's *almost* like you've decided you already personally own Reticulum. + +> The pattern shows up off the codebase too. In late August 2026, after a badly-behaved crawler hammered his NomadNet git node with tens of thousands of requests + +Ah yes, so I got personally mad because it hit *my* node, and had a tantrum? + +The scraper was hitting *every node across the entire fucking intermesh*, from a high-bandwidth VPS, with no throttling, no regards for people's radio links, airtime concerns, metered connections or limited compute resources. + +For what reason? To gouge tens of **millions** of requests to a broken piece of shit software that an idiot deployed and left running without oversight, trying to infintely download **everything that everyone had ever put on their nodes several times over** on a recursive loop. + +Who made that stop? I did, because I [contacted](https://github.com/roogle-dev/reticulum-phantom/issues/4) the idiot and talked him out of it. + +Let's hear more of your brilliant ideas about how to "protect the commons" you fucking ape. + +> Qvist removed the volunteer moderator of the Reticulum subreddit, deleted roughly three years of posts, and closed it with a notice that ended “Well done, vibecoders. You ruined it for everyone.” + +The moderator was not moderating anything, and hadn't been for months. The precise original agreement with him for allowing him moderator rights was exactly the arrangement, that if the space was not moderated, it would be closed, and that I would maintain the final decision on that. + +This is now being spun into yet another [bottle of piss](https://reticulum.network/manual/brandolinis.html#recycled-wine-fermenting) by the dipshits like you. Well done, moron. + +> Around the same window the project’s Matrix room shut down and the GitHub issue tracker was hidden. + +Does time not exist in your alternate universe? The events you allude to are separated by month or years, and the rationales were clearly stated. You deliberately ignored all of that. + +Further, I did not manage or administrate the Matrix room. It was a community room, run by volunteers, flooded with spam and bad-faith actors. I had *zero* admin rights on it. The moderators of the room made that decision themselves, long after I had left - *to focus on actual work*. + +The development was *never* centered on the GitHub issue tracker, it ran over Reticulum long before the preposterous madhouse of GitHub was left behind for good, as it continues to do today, as is documented and stated several places (including the front-page of the repository you refuse to link to). + +Signal to noise ratio has gone up *significantly* because of that. The community is *more* alive, and more productive. + +You are literally making things up as you go. + +> One community member’s summary: for a supposedly decentralised network, the founder holds and uses a lot of centralised levers. + +Yes, let's just [invent](https://reticulum.network/manual/brandolinis.html#the-movement-of-a-dozen) another concerned "community member". Who? Some random nutjob on reddit? + +A random stranger of your choosing is not a "community member" that gets to decide how a highly complex engineering project is run. But damn man, you wish it worked that way. You wish it badly. + +> None of this is meant as a pile-on. + +Oh, *thanks*, you're SO *considerate* and full of empathy Leo! + +> The Reticulum Licence is presented as a shield for the commons + +**Because that is what it actually is.** + +How about trying to actually *prove* otherwise, with *a coherent argument*, instead of getting an LLM to spin a load of high-strung nonsense to further your deranged religion? + +> If your users are European public bodies + +Oh, those poor administrative organizations! Do you think I dedicated my life to empowering European Public Bodies, or actual people? + +> Then spend the effort you saved on the part that is actually hard: governance that survives the founder losing interest. + +[Ze Governance](https://reticulum.network/manual/brandolinis.html#a-history-of-what-works), again, I see. + +Maybe when you've worked 12 hours a day on a project for ten years, which is persistently flooded with this kind of profound idiocy, and kept going, can you begin to consider expounding your finer points on "losing interest". + +> The commons is not protected by a clause forbidding bad uses. + +It sure as hell ain't protected by pretending the world is made of candy-floss either, like you seem to prefer. + +> It is protected by how many people can fork it, ship it, and keep it running without asking anyone’s permission. + +Oh isn't that convenient now? How many can do that today? 99.999999% of the worlds population. What's the equation if we change to your beloved AGPL again, you moron? + +> Reticulum’s licence made that number smaller. + +[Mathematical failure](https://reticulum.network/manual/brandolinis.html#on-freedom). + +> The intention was to guard the commons. The effect was to fence off a piece of it. + +On the intent, [correct](https://reticulum.network/manual/brandolinis.html#what-the-reticulum-license-is). + +On the effect, no: The effect apparently was to induce the uncomfortable feeling of grinding against your own inconsistent dogmas in dishonest, propagandistic nutjobs like you, because *you* now feel *fenced out*. + +There's an important difference there. + +The self-referential circle-jerk you've got going on here is *exactly* the definition of a fence; one made of hysteria and propaganda with the ulterior motive of usurping power away from a community of thousands of people, and putting it, squarely, into your own, trembling, wanting and lazy little hands. + +> Reticulum is also not a toy. People run it over LoRa and packet radio for emergency and off-grid communication, so “someone degrades the network” is a safety question, not an inconvenience. + +**Bingo**, Leo. + +Which is why you need a *real* [responsible, accountable and competent person](https://reticulum.network/manual/brandolinis.html#a-history-of-what-works), with a decade-long track-record to run the project, not a bunch of kids with a fixation on Claude, and their sugardaddies like you. + +> Here is the part that frustrates me. + +Yes, you must *surely* be frustrated Leo, how very frustrating this must be for you and your ChatGPT subscription to have to go through all of this. + +Tell me about frustration once you have actually done something that required more than pillow-fucking your own sense of grandiosity. + +All your github repos are minor personal projects with up to... count them... coooount them... five stars. No users. You must surely know a lot about software development, distribution, and these commons you are protecting so heroically. + +I can see you have a lot of skin in the game here, and a lot of work and experience on your back to bolster your authority. + +Fuck off, you fraud. + +> Every few years a piece of infrastructure I care about gets a new licence + +You don't care one fucking bit about infrastructure Leo. *You don't even know what it is*, least of all what it takes to create it. + +I do. Because I did it. + +Go home, you're drunk. + +Thanks for the material, though. You've provided a textbook example of the incessant bullshit, appropriation, deliberate enclosure and intentionally weaponized manipulation that [this project is up against](https://reticulum.network/manual/brandolinis.html#intent-consequence). + +*In ideology and war, self-justification wears the same coat, and feeds the same destruction, perpetually.* + +Yours truly, + +Mark Qvist + +September 18th, 2026 + +--- + +That it is, I am no longer angry. Back to work. \ No newline at end of file diff --git a/docs/history/2026_09_21_Void_Grants.md b/docs/history/2026_09_21_Void_Grants.md new file mode 100644 index 00000000..90bbe21a --- /dev/null +++ b/docs/history/2026_09_21_Void_Grants.md @@ -0,0 +1,253 @@ +## Void Grants: Legal Foundations of Machine-Generated Code +*From the [Brandolini's Reference](https://reticulum.network/manual/brandolinis.html) chapter of the Reticulum Manual.* + +A grant of rights is only as real as the rights behind it. A license conveys what its issuer holds, and nothing more. A derivative may be distributed only under whatever license covers what it took. And over a work that a machine originated, no human holds anything at all. + +Each of these statements is a matter of settled statute and case law, and this document sets out the authorities. The conclusions they support are: + +1. A software implementation generated from a licensed work by a machine, published under its operator's claimed copyright and license, **conveys rights the operator never possessed**. +2. **Its grant is void**. The projects, products, and promises built upon such grants stand on nothing. A field of void grants is a minefield for everyone who crosses it. + +This document is a general examination of copyright law as it applies to machine-generated code. It is not legal advice. + +### I. The Foundational Statute: Translation Is Copying + +The starting point is the statutory definition of the class of works at issue. Title 17, United States Code, section 101 provides the definition of a derivative work: + +> A "derivative work" is a work based upon one or more preexisting works, such as a *translation*, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or *any other form in which a work may be recast, transformed, or adapted*. + +Section 101 further provides that *"the terms 'including' and 'such as' are illustrative and not limitative"*. As such, the list is a list of *examples*, and the very first example is translation. The definition also reaches, in its own words, *"any other form in which a work may be recast, transformed, or adapted"*. + +The exclusive right at issue is defined in section 106: + +> Subject to sections 107 through 122, the owner of copyright under this title has the exclusive rights to do and to authorize any of the following: +> (1) to reproduce the copyrighted work in copies or phonorecords; +> (2) to prepare derivative works based upon the copyrighted work; +> (3) to distribute copies or phonorecords of the copyrighted work to the public by sale or other transfer of ownership, or by rental, lease, or lending; + +Violation of any of these rights is infringement. 17 U.S.C. § 501(a). + +Taken together, the provisions yield a construction that is difficult to improve upon and impossible to escape: + +1. **A port is a translation.** A work that takes a program written in one language and from it produces a program written in another language, implementing the same behavior, is a translation of the original - whatever mechanism performed it, and however the surface presentation differs. +2. **A translation is a derivative work.** Section 101 says so, explicitly. +3. **Preparing a derivative work is the copyright owner's exclusive right.** Section 106(2) says so explicitly. A derivative work prepared without authorization, or outside the scope of any authorization, infringes that right. + +The common objection - "the code is in a different language, so it is completely different" - is not a legal argument; it is the definition of what the statute already classifies. + +Translation *is the paradigm* of derivative authorship, not an exception to it. If translating a work without permission was a defense, the derivative-work right would be meaningless; every infringing adaptation would simply need to be "different enough" to count as a translation of its source. + +Nor does the identity of the translator change the analysis. The statute asks whether the work is "based upon" a preexisting work. It does not ask who or what performed the translation. A machine that ingests a licensed work and reproduces a translated transformation of it has performed mechanical translation; the output is a derivative of the ingested work, and the law governing derivative works applies to it exactly as it applies to a translation made by hand. + +### II. Ideas Are Free, Expressions Protected + +The second foundation is the distinction between what a work *is* - its ideas, its processes, its systems - and the *expression* in which those ideas are embodied. The distinction is codified in section 102(b): + +> In no case does copyright protection for an original work of authorship extend to any idea, procedure, process, system, method of operation, concept, principle, or discovery, regardless of the form in which it is described, explained, illustrated, or embodied in such work. + +The principle is older than the statute, and its application to software is settled. An author may own the particular code in which a method is expressed; the method itself, the process, the algorithm, belongs to no one - because *"the sine qua non of copyright is originality"* (*Feist Publications, Inc. v. Rural Telephone Service Co.*, 499 U.S. 340, 345. 1991). And ideas are not original to anyone in particular, *Baker v. Selden*, 101 U.S. 99 (1879), established the line: Copyright in a book describing a system does not prevent others from practicing the system. + +Applied to a communications protocol, the structure is clean: + +--- + +**An implementation of a public-domain protocol, honestly reasoned and written by humans, is welcome and unencumbered, and owes nothing to any license. An implementation generated from a licensed implementation is a derivative of licensed work, subject to its conditions and to the ordinary copyright of its source.** + +--- + +The public-domain status of the protocol's ideas changes nothing about the copyright in an implementation's expression. A person who copies an implementation - by machine or by hand - cannot defend the copying by pointing to the protocol, because the protocol covers the ideas, not the symbols in which someone expressed them. + +A further misconception can be dismissed here; the recently popularized "clean-room" claim about the absence of copying. A [clean-room](https://reticulum.network/manual/brandolinis.html#the-clean-room-delusion) is a not a magic label achievable by LLM, but a specific, institutionalized procedure for proving to a court that copying did not occur: Physically separated teams, written functional specifications, attestable non-exposure, and no access to the original by the implementers (*Altai*, 982 F.2d at 709–11). + +*"I created a clean-room implementation by feeding the original source code into a machine"* attempts to *claim* the certified, legally established procedure for proving the absence of copying by describing, in the same breath, a process **composed entirely of copying**. The word is deployed because the procedure it names is what the claimant would *need to have happened*. + +### III. Machine Output Has No Author + +The third foundation is the human authorship requirement. It is settled at both levels of the federal courts and in the Copyright Office's administering practice. + +In *Thaler v. Perlmutter*, the district court held that *"copyright law protects only works of human creation,"* and that *"human authorship is a bedrock requirement of copyright"* (687 F. Supp. 3d 140, 146, D.D.C. 2023). On appeal, the United States Court of Appeals for the District of Columbia Circuit affirmed, holding that the Copyright Act *"requires all eligible works to be authored in the first instance by a human being"* (No. 23-5233, D.C. Cir. Mar. 18, 2025). + +The requirement traces to the ordinary meaning of the statutory term. In *Burrow-Giles Lithographic Co. v. Sarony*, the Supreme Court defined an "author" as *"he to whom anything owes its origin; originator; maker; one who completes a work of science or literature"* (111 U.S. 53, 57–58, 1884), and more recently described the author as *"the person who translates an idea into a fixed, tangible expression entitled to copyright protection"* (*Community for Creative Non-Violence v. Reid*, 490 U.S. 730, 737, 1989). + +--- + +**A machine does not owe expression its origin; it reproduces it. No court has recognized copyright in material created by non-humans, and the courts that have addressed the question have rejected it. If you create by machine generation, you do not own the output.** + +--- + +The Copyright Office's registration guidance applies the requirement to generative systems in terms that are directly on point. The Office asks: + +> whether the "work" is basically one of human authorship, with the computer [or other device] merely being an assisting instrument, or whether the traditional elements of authorship in the work (literary, artistic, or musical expression or elements of selection, arrangement, etc.) were actually conceived and executed not by man but by a machine. + +- *Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence*, 88 Fed. Reg. 16190, 16192 (Mar. 16, 2023) + +And it states the consequence: *"If a work's traditional elements of authorship were produced by a machine, the work lacks human authorship and the Office will not register it"* (*Id.*). + +On the role of prompts, the Office is equally explicit: when a system receives a prompt and produces a work in response, *"these prompts function more like instructions to a commissioned artist - they identify what the prompter wishes to have depicted, but the machine determines how those instructions are implemented in its output"* (*Id.*). + +The agency applied this standard and excluded machine-originated material from registration in the leading administrative case. In *Zarya of the Dawn* (Cancellation Decision, Feb. 21, 2023, Registration No. VAu001480196), the Office cancelled registration of images generated by the Midjourney service, holding that *"it was Midjourney-not [the author]-that originated the 'traditional elements of authorship' in the images"*, while preserving protection for the human-authored text and the human selection and arrangement of the work. + +The Copyright Office's 2025 report on AI copyrightability reaches the same conclusion: + +> Based on the functioning of current generally available technology, prompts do not alone provide sufficient control. + +- U.S. Copyright Office, *Copyright and Artificial Intelligence, Part 2: Copyrightability*, at iii (Jan. 29, 2025) + +The report's analysis is explicit: *"The Office concludes that, given current generally available technology, prompts alone do not provide sufficient human control to make users of an AI system the authors of the output. Prompts essentially function as instructions that convey unprotectible ideas"* (*Id.* at 18). + +Its guiding distinction is stated plainly: *"The use of AI tools to assist rather than stand in for human creativity does not affect the availability of copyright protection for the output"* while *"Copyright does not extend to purely AI-generated material, or material where there is insufficient human control over the expressive elements"* (*Id.* at iii). + +The boundary is therefore not "AI or no AI". It is *assistance or substitution*: Whether a human exercised sufficient creative control over the expressive elements and can answer for them, or whether the machine originated them and the human merely supplied instructions and a signature. That is a question of fact in each case, determined from the record of how the work was made. + +Two facts follow, and stated together, they form the base legal reality: + +1. **A work whose expressive elements were originated by a machine contains no valid new copyright: It has no human author. To the extent that the same work reproduces a preexisting copyrighted work without explicit license, it is at the same time an unauthorized derivative. It is unowned for anything new it contains, and unlicensed for everything taken.** +2. **Its operator therefore holds no copyright in it and no grant over it - and a person who holds neither copyright nor grant can convey neither.** + +The first fact makes the work **unownable** by its operator. The second makes it infringing against its source. Neither replaces the other: + +- The absence of copyright in machine output does not make the output free for anyone to take; it makes it unowned. +- This is a different thing entirely, especially when what it contains is someone else's expression. + +### IV. License Conditions Bound the Grant + +The fourth foundation governs what a license *is*. A copyright owner may grant permission to use the work on conditions. The conditions define the scope of the permission. Use outside the scope is use that was never authorized. + +In *Jacobsen v. Katzer*, 535 F.3d 1373 (Fed. Cir. 2008), the Federal Circuit held that the conditions of an open-source license are *conditions of the copyright license itself*, not mere contractual promises, and that a licensee operating outside them is an infringer: + +> Copyright holders who engage in open source licensing have the right to control the modification and distribution of copyrighted material. + +> The choice to exact consideration in the form of compliance with the open source requirements of disclosure and explanation of changes, rather than as a dollar-denominated fee, is entitled to no less legal recognition. + +> It is outside the scope of the [license] to modify and distribute the copyrighted materials without copyright notices and a tracking of modifications from the original computer files. + +- *Id.* at 1381–82 + +The doctrinal mechanism is settled: *"A copyright owner who grants a nonexclusive license to use his copyrighted material waives his right to sue the licensee for copyright infringement"* within the scope of the license. If, however *"the licensee acts outside the scope, the licensor can bring an action for copyright infringement"*: An act outside the granted scope **is infringement** (*Sun Microsystems, Inc. v. Microsoft Corp.*, 188 F.3d 1115, 1121, 9th Cir. 1999; *Graham v. James*, 144 F.3d 229, 236, 2d Cir. 1998; *S.O.S., Inc. v. Payday, Inc.*, 886 F.2d 1081, 1087, 9th Cir. 1989). + +Whether a given license term is a condition of the grant or a mere covenant is determined from the license's own language; conditions that limit what may be copied, modified, and distributed - the attribution terms, the notice terms, the modification-tracking terms, the field-of-use terms - are the boundaries of the copyright grant (*MDY Industries, LLC v. Blizzard Entertainment, Inc.*, 629 F.3d 928, 940, 9th Cir. 2010). + +Three consequences follow for the analysis at hand. They are not hypothetical. + +**First, the conditions are measured at the moment of copying** + +A work is licensed under whatever conditions applied when the reproduction, adaptation, and distribution occurred. There is **no** period in which copying a licensed work is "free" because the copy was made by a machine; the machine is the *licensee's tool*, and the licensee is bound by the conditions regardless. A derivative generated without satisfying the conditions - without the attribution, without authorization for the manner of use - was never within the scope of the license, from the first instant of its existence. + +**Second, breach does not restore rights that never attached** + +The district court in *Artifex Software, Inc. v. Hancom, Inc.*, No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017), analyzing the GPL's termination provisions, observed that *"the language of the GPL suggests that [the licensee's] obligations persisted beyond termination of its rights to propagate software using Ghostscript,"* because the source-code obligation recurs each time a covered work is conveyed. The same structure operates a fortiori where a derivative was produced *outside* the license entirely: No grant ever attached, and no subsequent event creates one. + +**Third, the settled conditions are the enforceable core** + +The attribution and notice conditions rest on the settled doctrine above. Novel conditions (restrictions on field of use, restrictions on how the work may be consumed) are enforceable as conditions of the grant when clearly drafted, but their enforcement history is thinner. The argument that a derivative is unlicensed does *not* depend on the novel conditions being vindicated; it needs **only** the settled ones, and the ordinary law of derivative works, to stand. + +### V. The Void Grant + +The preceding sections assemble into a single structure. Let us apply it to an example situation: + +- A project presented as an independent implementation of a protocol; "ground-up", "from scratch" or "clean-room" work. +- The actual history shows continuous, machine-mediated ingestion of a licensed reference implementation. +- The output is generated at a scale no human could produce or review, with the provenance of the process obscured. + +**Step One: The derivative** + +The project's output is a translation of the licensed implementation: A derivative work, produced by a copy process. 17 U.S.C. §§ 101, 106(2). Preparing it without authorization infringed from the first moment of its existence. *Id.* § 501(a). + +**Step Two: The license** + +The derivative was produced outside the conditions of the license; without the notices, without the attribution. The license never attached (*Jacobsen*, 535 F.3d at 1381–82). + +**Step Three: Authorship** + +The expression was originated by a machine. No human can account for its creative decisions, and no human authored it. It contains no valid new copyright (*Thaler*, 687 F. Supp. 3d at 146; No. 23-5233, D.C. Cir. 2025; 88 Fed. Reg. at 16192). + +**Consequence: Void Grant** + +The statute supplies the consequence. Section 103(a) provides: + +> The subject matter of copyright as specified by section 102 includes compilations and derivative works, but protection for a work employing preexisting material in which copyright subsists does not extend to any part of the work in which such material has been used unlawfully. + +And section 103(b) provides that copyright in a derivative work *"extends only to the material contributed by the author of such work."* The legislative history states the point without ambiguity: *"An unauthorized translation of a novel could not be copyrighted at all"* (H.R. Rep. No. 94-1476, at 57, 1976). + +In our example, the operator of the derivative's copy process decides to assert copyright over the output, and licenses it to the world under terms of the operator's choosing, for example the Apache License. + +But the operator holds no copyright in machine-originated content (section III) and no license over the source from which it was derived (sections I and IV). + +For the derived material, the operator's copyright claim **is an assertion of a right that never existed**. The material was used unlawfully, and section 103(a) withholds protection from *every* part of the work in which it appears. For the machine-originated remainder, the operator holds no copyright either, for lack of any human author. + +The operator's license to the world is a promise the operator had no power to make. Every person who receives the work believing they received a valid grant has received **a void grant**, and stands, as a matter of settled law, in the position of a downstream user of an unauthorized derivative, whatever they were told at the time. + +This is a cascading consequence, and it is why the pattern is a hazard. No combination of self-granted licenses - "MIT," "Apache," "public domain," anything at all - can transfer rights the operator never held. Every downstream project, product, or deployment built on the derivative is built on unlicensed reproduction of a third party's work, whether or not it knew, whether or not it was told, and whether or not the marketing was plausible. + +The longer the derivative circulates unexamined, the more it becomes embedded, forked, vendored, depended upon, and the more expensive its correction becomes for everyone who trusted it. A field of superficially real projects, repositories, and licenses that **in reality confer nothing on anyone who relies on them is a minefield**, in the most precise sense the law allows: The rights they purport to grant *were never possessed*. + +The law defines what may be asserted, not what will be. The copyright owner may choose whether and how to assert these rights, and at what point in time. The exposure exists regardless, and for *every* downstream that trusted the void grant. This is the scope of the hazard that the conduct exemplified here produces. + +### VI. Fair Use Does Not Rescue This Pattern + +Every defendant raises fair use. It is an essential and important limitation in the service of free speech, accountability, criticism, education and other important domains. Therefore, it must be considered, and in the case exemplified here, it fails. + +Fair use is a limitation on the exclusive rights, evaluated case by case under four factors: The purpose and character of the use; the nature of the copyrighted work; the amount and substantiality of the portion used; and the effect of the use on the potential market for or value of the work (17 U.S.C. § 107). + +On the first factor, the governing standard is *Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith*, 598 U.S. 508 (2023), in which the Supreme Court held that: + +> In sum, the first fair use factor considers whether the use of a copyrighted work has a further purpose or different character, which is a matter of degree, and the degree of difference must be balanced against the commercial nature of the use + +The question is whether the use serves a further purpose, not whether the surface changed. A derivative that exists to serve as the same thing as the original, marketed to the people who would otherwise use the original, has not acquired a further purpose by being translated; the surface changed, the function did not, and the use is commercial. + +The remaining factors resolve the same way. Source code is expressive creative work, not bare fact. The pattern under examination copies the whole; a complete implementation, ingested and translated in its entirety. And the market effect is the decisive factor, because it is engineered: A derivative marketed as a drop-in replacement for the work it was copied from is not a complement to the original's market, it is a substitute for it. The Supreme Court has long held that use of a work to satisfy the market demand for the original is the paradigm of an *unfair* use (*Harper & Row, Publishers, Inc. v. Nation Enterprises*, 471 U.S. 539, 566–67, 1985). + +The one case that is always raised in response, *Google LLC v. Oracle America, Inc.*, 593 U.S. 1 (2021), holds less than it is believed to. The Court there assumed *"for argument's sake, that the material was copyrightable"* and held *"that the copying here at issue nonetheless constituted a fair use"* (*Id.* at 11). + +The material in question was a thin slice of *declaring code*, which the Court found sits, *"if copyrightable at all, further than are most computer programs (such as the implementing code) from the core of copyright"* (*id.*), in a use that built a new platform for a new environment, with the copier **having written the vast majority of its own code**. By comparison: A wholesale translation of an entire implementation, marketed as a substitute for it, is **not** that case; it is the other end of every factor. + +The valuable zones of fair use remain, and they are important. **Commentary and criticism**, quoting from a work to review, discuss or criticize it. **Teaching and scholarship**, explaining concepts and quoting excerpts, is its traditional beneficiary. + +### Conclusion + +The law is neither obscure nor new. The conclusion it yields can now be stated: + +- A machine translation of a protected implementation **is a derivative work**, and an unauthorized derivative **is an infringement**, whatever language it speaks and whatever machinery produced it. +- A work whose expression a machine originated has no human author, no valid new copyright, and without valid copyright **no license can be granted on it**. +- § 103 withholds protection from every part of a derivative in which protected material was used unlawfully. A license is a grant with conditions, and a derivative made outside the conditions **never received a grant**. +- A person who holds no copyright and no grant **can convey neither**, and *every* downstream consumer who received from them received a **void grant**. + +This is a *catastrophic* failure state for all who want to create things good and useful: The projects that inherit only void grants and liability believing they have inherited foundations, the users who depend on code that no one on earth can answer for, the honest builders whose work is buried under a field of plausible-looking impostors. + +### Sources and Authorities + +Statutory references are to Title 17, United States Code. Case citations are to the official or generally cited reporters. Online links are for reference only. Section numbers refer to the sections of this document in which each authority is principally relied upon. + +**Statutes** + +- [17 U.S.C. § 101 (definitions: "derivative work," "including," "publication") - I, II](https://www.law.cornell.edu/uscode/text/17/101) +- [17 U.S.C. § 102(b) (idea/expression) - II](https://www.law.cornell.edu/uscode/text/17/102) +- [17 U.S.C. § 103(a)–(b) (derivative works employing unlawfully used preexisting material) - V](https://www.law.cornell.edu/uscode/text/17/103) +- [17 U.S.C. § 106(1)–(3) (exclusive rights: reproduction, derivative works, distribution) - I](https://www.law.cornell.edu/uscode/text/17/106) +- [17 U.S.C. § 107 (fair use) - VI](https://www.law.cornell.edu/uscode/text/17/107) +- [17 U.S.C. § 501(a) (infringement) - I, V](https://www.law.cornell.edu/uscode/text/17/501) + +**Judicial decisions** + +- [*Jacobsen v. Katzer*, 535 F.3d 1373 (Fed. Cir. 2008) - IV, V](https://www.casemine.com/judgement/us/5914b290add7b04934760a54) +- [*Sun Microsystems, Inc. v. Microsoft Corp.*, 188 F.3d 1115 (9th Cir. 1999) - IV](https://law.justia.com/cases/federal/appellate-courts/F3/188/1115/629501/) +- [*Graham v. James*, 144 F.3d 229 (2d Cir. 1998) - IV](https://caselaw.findlaw.com/court/us-2nd-circuit/1011522.html) +- [*S.O.S., Inc. v. Payday, Inc.*, 886 F.2d 1081 (9th Cir. 1989) - IV](https://law.justia.com/cases/federal/appellate-courts/F2/886/1081/19091/) +- [*MDY Industries, LLC v. Blizzard Entertainment, Inc.*, 629 F.3d 928 (9th Cir. 2010) - IV](https://law.justia.com/cases/federal/appellate-courts/ca9/09-15932/09-15932-2011-02-25.html) +- [*Artifex Software, Inc. v. Hancom, Inc.*, No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017) (settled; dismissed with prejudice Jan. 2018) - IV](https://storage.courtlistener.com/recap/gov.uscourts.cand.305835/gov.uscourts.cand.305835.54.0_1.pdf) +- [*Thaler v. Perlmutter*, 687 F. Supp. 3d 140 (D.D.C. 2023), aff'd, No. 23-5233 (D.C. Cir. Mar. 18, 2025) - III, V](https://www.bitlaw.com/source/cases/copyright/Thaler-Perlmutter-Dct.html) +- [*Burrow-Giles Lithographic Co. v. Sarony*, 111 U.S. 53 (1884) - III](https://supreme.justia.com/cases/federal/us/111/53/) +- [*Community for Creative Non-Violence v. Reid*, 490 U.S. 730 (1989) - III](https://supreme.justia.com/cases/federal/us/490/730/) +- [*Feist Publications, Inc. v. Rural Telephone Service Co.*, 499 U.S. 340 (1991) - II](https://supreme.justia.com/cases/federal/us/499/340/) +- [*Baker v. Selden*, 101 U.S. 99 (1879) - II](https://supreme.justia.com/cases/federal/us/101/99/) +- [*Computer Associates International, Inc. v. Altai, Inc.*, 982 F.2d 693 (2d Cir. 1992) - II](https://law.justia.com/cases/federal/appellate-courts/F2/982/693/137252/) +- [*Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith*, 598 U.S. 508 (2023) - VI](https://www.supremecourt.gov/opinions/22pdf/21-869_87ad.pdf) +- [*Google LLC v. Oracle America, Inc.*, 593 U.S. 1 (2021) - VI](https://supreme.justia.com/cases/federal/us/593/18-956/) +- [*Harper & Row, Publishers, Inc. v. Nation Enterprises*, 471 U.S. 539 (1985) - VI](https://supreme.justia.com/cases/federal/us/471/539/) + +**Administrative and policy authorities** + +- [*Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence*, 88 Fed. Reg. 16190 (Mar. 16, 2023) - III](https://www.federalregister.gov/documents/2023/03/16/2023-05321/copyright-registration-guidance-works-containing-material-generated-by-artificial-intelligence) +- [*Zarya of the Dawn*, U.S. Copyright Office (Cancellation Decision, Feb. 21, 2023), Registration No. VAu001480196 - III](https://www.copyright.gov/docs/zarya-of-the-dawn.pdf) +- [U.S. Copyright Office, *Copyright and Artificial Intelligence, Part 2: Copyrightability* (Jan. 29, 2025) - III](https://www.copyright.gov/ai/Copyright-and-Artificial-Intelligence-Part-2-Copyrightability-Report.pdf) +- [H.R. Rep. No. 94-1476 (1976) - V](https://law.resource.org/pub/us/works/aba/ibr/H.Rep.94-1476.pdf) diff --git a/docs/manual/.buildinfo b/docs/manual/.buildinfo index 0a93c42c..85787315 100644 --- a/docs/manual/.buildinfo +++ b/docs/manual/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file records the configuration used when building these files. When it is not found, a full rebuild will be done. -config: c647a5f163ca6db1b075e5978b13a8fb +config: a83095d108892439ad6027acd44f7c0a tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/manual/_images/columba.webp b/docs/manual/_images/columba.webp new file mode 100644 index 00000000..07ea65ed Binary files /dev/null and b/docs/manual/_images/columba.webp differ diff --git a/docs/manual/_images/meshchatx.webp b/docs/manual/_images/meshchatx.webp index 24fd7ba0..94edb72a 100644 Binary files a/docs/manual/_images/meshchatx.webp and b/docs/manual/_images/meshchatx.webp differ diff --git a/docs/manual/_images/modem73.webp b/docs/manual/_images/modem73.webp new file mode 100644 index 00000000..5adadc76 Binary files /dev/null and b/docs/manual/_images/modem73.webp differ diff --git a/docs/manual/_images/nomadnet_3.png b/docs/manual/_images/nomadnet_3.png deleted file mode 100644 index 4a8c0def..00000000 Binary files a/docs/manual/_images/nomadnet_3.png and /dev/null differ diff --git a/docs/manual/_images/nomadnet_6.webp b/docs/manual/_images/nomadnet_6.webp new file mode 100644 index 00000000..3f973658 Binary files /dev/null and b/docs/manual/_images/nomadnet_6.webp differ diff --git a/docs/manual/_images/partyline.webp b/docs/manual/_images/partyline.webp new file mode 100644 index 00000000..ac7d96c1 Binary files /dev/null and b/docs/manual/_images/partyline.webp differ diff --git a/docs/manual/_images/rbrowser.webp b/docs/manual/_images/rbrowser.webp deleted file mode 100644 index e717d2b4..00000000 Binary files a/docs/manual/_images/rbrowser.webp and /dev/null differ diff --git a/docs/manual/_images/ren_browser.webp b/docs/manual/_images/ren_browser.webp new file mode 100644 index 00000000..6a6223ec Binary files /dev/null and b/docs/manual/_images/ren_browser.webp differ diff --git a/docs/manual/_images/rentui.webp b/docs/manual/_images/rentui.webp new file mode 100644 index 00000000..0c40fad6 Binary files /dev/null and b/docs/manual/_images/rentui.webp differ diff --git a/docs/manual/_images/reticulated.webp b/docs/manual/_images/reticulated.webp new file mode 100644 index 00000000..ebd2a67e Binary files /dev/null and b/docs/manual/_images/reticulated.webp differ diff --git a/docs/manual/_images/retipedia.webp b/docs/manual/_images/retipedia.webp new file mode 100644 index 00000000..8ffe1a0f Binary files /dev/null and b/docs/manual/_images/retipedia.webp differ diff --git a/docs/manual/_images/rngit.webp b/docs/manual/_images/rngit.webp new file mode 100644 index 00000000..5e1f54e4 Binary files /dev/null and b/docs/manual/_images/rngit.webp differ diff --git a/docs/manual/_images/rrc.webp b/docs/manual/_images/rrc.webp new file mode 100644 index 00000000..56889713 Binary files /dev/null and b/docs/manual/_images/rrc.webp differ diff --git a/docs/manual/_sources/brandolinis.rst.txt b/docs/manual/_sources/brandolinis.rst.txt new file mode 100644 index 00000000..334dc662 --- /dev/null +++ b/docs/manual/_sources/brandolinis.rst.txt @@ -0,0 +1,1625 @@ +.. _brandolinis-main: + +Brandolini's Reference +====================== + + | *A little learning is a dang’rous thing;* + | *Drink deep, or taste not the Pierian spring.* + | *There shallow draughts intoxicate the brain,* + | *And drinking largely sobers us again.* + | + | - Alexander Pope, 1711 + +This chapter serves as a helpful reference for developers, users and community members living in an Age of Bullshit Manufacture equivalent to the Cambrian Explosion. + +As we are surely only at the on-ramp of this trajectory, the chapter will continue to evolve, expand and be updated based on community feedback as events occur. + +.. _brandolinis-what-the-license-is: + +What The Reticulum License Is +----------------------------- + +*To understand the legal reality relating to this section, see* :ref:`Void Grants`. + +The :ref:`Reticulum License` is the license under which RNS, the Reticulum reference implementation, has been published since **April 15, 2025**\ , in versioning effective from **0.9.4** and every release since. In practical terms, it covers all of "modern Reticulum": The current wire format, the cryptographic machinery as it exists today (including the AES-256-based link encryption, ratchets, et cetera), and all protocol additions that distinguish the modern implementation from the earliest pre-1.0.0 beta formats. If an implementation speaks today's Reticulum protocol, it is, in all relevant respects, built on Reticulum-licensed work. + +The license is a permissive license. It grants the full range of rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, free of charge; subject to three conditions, which are reproduced here verbatim: + +.. + + * + The Software shall not be used in any kind of system which includes amongst its + functions the ability to purposefully do harm to human beings. + + * + The Software shall not be used, directly or indirectly, in the creation of an artificial + intelligence, machine learning or language model training dataset, including but not + limited to any use that contributes to the training or development of such a model or + algorithm. + + * + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + +.. _brandolinis-why-the-license-exists: + +Why This License Exists +^^^^^^^^^^^^^^^^^^^^^^^ + +Reticulum was not moved to a custom license casually or quickly. It was licensed under the MIT license for the greater part of its existence, and that served well for a long time. The change came when it became clear that no existing license expressed what the project needed, and that the two most commonly proposed alternatives would either say the wrong thing or say nothing useful at all. Three factors had primary influence on the situation: + +**The harm problem** + +Reticulum is a tool that was built, deliberately and at great cost, to empower people; to make communication something you own rather than something you are temporarily granted. It has also been, at various times, exactly what certain kinds of organisations would like to use to control people. This is the duality of any powerful tool. A permissive license could not, and cannot, say anything about that; MIT is silent on the question of whether the software may be used to build systems designed to harm human beings. The Reticulum License is not silent. It does not pretend that a license can stop an individual madman; it does assert, however, plainly and in enforceable terms, that corporations and organisations integrated into the legal system cannot consume this software for harm and then claim they never knew. The line is drawn by the creators of the tool, not by an external authority, and it is drawn deliberately. This is covered in more depth in the discussion of the ethics of the tool in the *Zen of Reticulum*. + +**The appropriation problem** + +The second factor was the machine-learning appropriation of the open-source commons. By 2025 that was no longer hypothetical: The commons was already being systematically ingested by corporate training pipelines, and the code, words, and creativity of the people who built it were being converted into synthetic systems designed to replace them. The license responds to this with an explicit condition: The software shall not be used in the creation of an AI, machine-learning, or language-model training dataset, nor in any use that contributes to the training or development of such a model or algorithm. + +It is important to understand what this condition does and does not do, which matters for what follows in this chapter. **The AI-training condition is not the legal basis for protecting the code from machine copying**. That protection *already exists*\ , in the oldest and most well-tested form of copyright law, and it applies regardless of any license (see :ref:`Copyright & The Two Legal Layers`). + +The AI-training condition addresses something *additional*\ : the appropriation of the code *into the models themselves*\ ; the ingestion of human-made work as raw material for a synthetic replacement, and the use of that ingestion to fabricate "prior work" minefields, patent-troll material, and a wall of slop meant to bury and devalue the actual ecosystem. That danger was foreseeable; the licensing decision was made with full awareness of it. The events of 2026 have since demonstrated, in public and in detail, that the concern was not theoretical. + +**The sustainability problem** + +Reticulum has been developed and maintained for over a decade by a single person, supported by a small group of contributors and network-building users, without corporate backing, without VC funding, through several serious attempts at commercialization and takeover from both the corporate and the ideological side. The license is part of what makes that sustainable, and possible at all. + +It ensures that the specific, painstaking labor of the reference implementation cannot be hijacked to undermine the intent of the project, while leaving the protocol itself, the mathematical rules of how Reticulum works, dedicated to the public domain, where it belongs to humanity and can never be owned. Anyone can implement the protocol, provided they themselves invest the *actual* work and effort. What the license protects is the work, and the intent embodied in it. + +.. _brandolinis-on-freedom: + +On Freedom +^^^^^^^^^^ + +The most persistent mischaracterisation of the Reticulum License is that it is "more restrictive" than the licenses it replaced or than the GPL family. This is backwards, and I'll state the comparison plainly, because the confusion is the foundation of a great deal of deliberately manufactured controversy examined later in this chapter. + +The GPL and AGPL are constructed around a single, self-referential axiom: that "free" is *defined by the terms of the license itself*\ , and that any use falling outside those terms is not free. In practice, this means the GPL restricts the freedom of **everyone** - you may not write, distribute, link, or (in some cases) even communicate with GPL-covered software without the entire arrangement being pulled under the same terms, which the licensor then controls. The restriction applies to 100% of users, including the ones building purely constructive things. + +The Reticulum License restricts the freedom of almost nobody. Its restrictions apply only to: + +* Those who wish to use the software in systems that purposefully harm human beings, and +* Those who wish to ingest the software into AI training pipelines. + +That is a restriction on a vanishingly small fraction of would-be users - the 0.0000001% - and it is a restriction they can characterise however they like, forever. The bickering is itself a signal that the licensing decision hit exactly the right target. + +Everyone else retains the full breadth of use, modification, distribution, and sale, with none of the viral encumbrance of copyleft. + +Both licenses contain moral axioms. The difference is that the Reticulum License states its axioms out loud: + +* *Intentionally restricting the way that millions of people use and build upon a foundational + communications technology* - **The mechanism of copyleft** +* *Intentionally restricting a small number of organisations from using the technology to + violently harm human beings* - **The mechanism of the Reticulum License** + +Which of these is more free? The answer is not a matter of committee approval. It is a matter of what the word "free" means to the people *whose freedom is at stake*. The question of whether "open source" requires the blessing of a particular licensing orthodoxy is examined in :ref:`Open Source Means Open Source`. + +.. _brandolinis-prediction: + +The Prediction, And What Happened +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When the license change was made and publicly discussed in 2025, the following was said, in public, about the machine-learning threat: + +.. + + A generative system could be trained on the Reticulum codebase, and for extremely low cost + be set to work spewing out millions of source repositories for all kinds of ridiculous + "Reticulum-based programs". This is already happening. You can find several examples of this + on GitHub already. … the point of this kind of trolling is to establish as wide a base for + "prior work" as possible. By doing that, a patent troll or IP abuser can create an immense + minefield for real developers. + + +This was written when the phenomenon was just beginning. It was not a guess; it was a description of a mechanism already in motion, in the specific context of Reticulum, by people who had already begun to appear around the project. + +Less than a year and a half later, the prediction has now been demonstrated, in public, exhaustively and to the letter. There are now roughly a dozen machine-generated "Reticulum implementations" of the same shape: fluent, marketing-heavy, some without attribution, and - in several cases - actively harmful to the network. The :ref:`Prns case` is an example documented in this chapter. The pattern that produced it (and the people, mechanisms, and the recycling of falsehoods behind the *wider* phenomenon) is examined in :ref:`A Movement Of A Dozen`. + +The license was written, in part, so that when this happened, the community would not be defenceless. + +.. _brandolinis-means-for-other-implementations: + +What This Means For Other Implementations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Two simple things must be kept separate: + +#. + **The protocol is public domain.** The mathematical rules of Reticulum - addresses, + signatures, routing, the wire format as an idea - belong to humanity. A *genuine* clean-room + implementation of the protocol, written by human beings who reasoned it out themselves, is + free and welcome, and owes nothing to the Reticulum License. Nothing in this chapter is an + argument against implementing the protocol. On the contrary: More good implementations, + honestly made, are good for the network. + +#. + **The implementation is licensed.** Copying the reference implementation - by machine or + by silk-screen press - and modifying and redistributing the result, is + exercising rights granted by the license, and is therefore subject to its conditions: The attribution + notice, the harm condition, the AI-training condition. A copy that does not follow those + conditions is **not** licensed, and it is not "open source in spirit"; it is an unauthorized + derivative work, and therefore a copyright violation. + +The distinction is the same one the license itself makes, and it must be held firmly: An implementation that *speaks* Reticulum is exercising the public domain protocol, **if** it was truly created independently. An implementation that was *generated from* RNS, reproduced by a copy process, is a derivative of licensed work. + +.. _brandolinis-copyright-and-layers: + +Copyright & The Two Legal Layers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The exact legal structure is frequently muddied in public discussion; and in several cases deliberately. + +**Layer A - Copyright (license-independent)** + +Copyright does not depend on any license. A primarily machine-generated copy of a copyrighted work - a copy not accompanied by demonstrable, substantial, new human creative input - is a derivative work over which the copier holds no copyright whatsoever, and the reproduction of which, without the original author's permission, is an infringement of the original author's copyright. This is standard, well-tested law, and it applies with equal force under the MIT license, the GPL, or any other license, because it is not about the license at all; it is about who created what. A process that copies the reference implementation into a machine, produces a transformed derivative, and then claims "Copyright, [name of the process operator]" - with no human able to account for the creative decisions in the result - **is not** asserting a valid copyright over the result. They are openly asserting the absence of one, and reproducing someone else's work without authorisation. This is probably the cleanest cut copyright violation one could imagine. + +**Layer B - License Conditions (Reticulum License specific)** + +Where a copy *is* a licensed derivative, the conditions of the Reticulum License apply: The copyright notice and permission notice must be included in all copies and substantial portions; the harm condition must be honoured; the AI-training condition must be honoured. A derivative that follows none of these is unlicensed *a second way over*. + +The two layers are often intentionally confused in public discussion - the AI-training condition is waved around as if the entire question of machine copying rested on it, when in fact machine copying of copyrighted work is a copyright violation that would exist even under the most permissive license ever written. The purpose of keeping the layers separate is not rhetorical flourish; it is that Layer A is old, settled law, and does not rely on any novel legal theory, while Layer B is specific to this license. Both matter. Neither is a substitute for the other. + +Layer B is the required mechanism for closing the loophole where the work is *first* ingested during model training into the weights of a model itself, which would make any resulting violations almost impossible to detect and enforce. + +.. _brandolinis-cleanroom-delusion: + +The "Clean-Room" Delusion +^^^^^^^^^^^^^^^^^^^^^^^^^ + +I regularly receive mail or LXMF messages from people who proudly and happily proclaim that they have created a "clean-room" implementation of one of the software systems I maintain; RNS, Sideband, LXMF or others. The declaration is delivered with the flat certainty of someone who believes they have found the legal lock-pick that settles everything at once: Their production is independent, uncontaminated, and therefore free of any obligation to the work they copied, its license, or its author. The proclamation usually concludes with a request for blessing, or at least acknowledgment. The proclamation is, usually, also generated by an LLM. + +This is a delusion, and I'll cut through it surgically. The word they here invoke as magic is attempting to do a great deal of work it was never able to bear. + +**What a clean room actually was** + +The legal "clean room" is not folklore, incantation, witchcraft or a claim a person gets to make about their own output. It is a very specific, institutionalized procedure that grew out of the hardware and software litigations of the 1980s, and it existed for exactly one purpose: **Convincingly proving the absence of copying in a court of law**. + +The canonical case was Phoenix Technologies and its 1984 reimplementation of the IBM PC BIOS. IBM's BIOS was copyrighted, which meant that the entire PC-compatible industry depended on being able to show that a compatible BIOS had been written independently, and not from IBM's code. Phoenix's answer was a physical and procedural firewall: + +* One team, the "dirty room", read the original code and produced written *functional specifications*\ : descriptions of what the BIOS did, not how IBM's code did it. +* A second team, the "clean room", consisted of engineers who had *never seen the original code at all*\ , and they wrote the new BIOS from those specifications alone. + +This obsessively documented, legally attested separation was not a preference or a willy-nilly show for a kindergarten; it was the entire legal point, and it had to be *solid*. If even one clean-room engineer had *glanced* at IBM's code, the clone would have been contaminated, and the defense would shatter. + +The other landmark case was *Computer Associates v. Altai* (1992), in which Altai had copied CA's scheduler code into its own product, and (upon being caught) hired outside counsel to run a genuine clean-room procedure: A programmer with no exposure to the original was brought in to rewrite the infringing modules from functional specifications prepared by the team that had seen the code. The court credited the good-faith effort precisely because it was done, as the carefully documented record showed, to the letter of the procedure. + +Bear in mind what this procedure entailed in practice, because this is the part the modern claimants never seem to have even *heard* of: Physical separation of teams, legal counsel managing the process, signed and notarised declarations of non-exposure, controlled specification documents that described *behaviour* and never *code*, months of work, and testing against the specification - not against the original, which the implementers were forbidden to consult. + +The people on the clean-room side of the wall did not just *claim* they had not read the code. Their non-exposure was institutionally guaranteed, obsessively documented, and legally attestable through every fart and sneeze of the process, because the entire point was that a court - hostile, adversarial, and entitled to discovery - would believe it. + +*That* is the process. "Clean-room implementation" is the name of a *certified procedure for proving independent authorship*. It is not a mood, a marketing label, or a property a person gets to declare about their own work. + +**The moronic inversion** + +Now consider what is actually being described when someone says: *"I created a clean-room implementation of Reticulum by feeding the source code into a machine."* + +That sentence is the opposite of a clean room. Feeding a copyrighted work into a machine so that it reproduces and transforms the work is **the definition of copying**\ , and a clean room is the one procedure whose entire purpose is the demonstrated *absence* of copying. This process cannot demonstrate the absence of copying, because the process is *composed of* copying. The cleanest possible room has been replaced by the dirtiest possible room, and the dirt has been installed as the base feature. What these claimants have actually performed is a photocopy with extra steps, and the extra steps, far from cleaning anything, are simply steps that forge a certificate they believe the output has earned. + +**Why the word is deployed** + +The word "clean-room" is deployed because it sounds like what the speaker wishes were true. It carries the accumulated legal prestige of the 1980s and 1990s - the BIOS clones, the Altai credit - and it sounds like a certificate already issued: *Independent, original, unencumbered*\ , the work of a person who owes nothing. The claimants want that halo without the procedure: No law firm, no physical separation, no written specifications, no signed declarations, no months of process - just a laptop, a loop, and the word "clean-room" typed into a README. The word must do the work of the process it replaces, and the delusional replacement is the entire point. + +**The irony runs deep** + +The Reticulum protocol is public domain. Any human being can implement it - from the mathematics, from the documentation, from their own reasoning - and owe nothing whatsoever to the license, to the reference implementation, or to me. + +An honestly written implementation needs no incantations, no legal theater, and no special vocabulary; it simply *is* what it claims. It's plain for everyone to see. **It's also plain for everyone to see when you're faking it**. The people who reach for the word "clean-room" are, without exception, the people who need it to create a fantasy - and the people who need that are precisely the people who cannot have it. If what you wrote were genuinely independent work on the public-domain protocol, you would not need to call it anything. The word is not a seal of independence. In this context it is a confession of copying, filed by the copier, in the confident belief that it says the opposite. + +.. _brandolinis-opensource: + +Open Source Means Open Source +----------------------------- + +An objection regarding the "open source status" of RNS appears occasionally in variations, but always reduces to the same syllogism: + + +#. "Open source" means *licensed under one of the licenses approved by the Open Source + Initiative (or, in other variants, compatible with GPL orthodoxy)*. +#. The Reticulum License is not on that list. +#. Therefore Reticulum is not open source, and anything built on it is illegitimate. + +The entire argument rests on the first premise, and the first premise is false. + +Open source is not a certification conferred by a committee. It is a description of a fact: The source code is available, and the rights to use, copy, modify, merge, publish, distribute, sublicense, and sell it are granted to everyone, free of charge. + +The Reticulum License does all of those things. It is, in every substantive respect that concerns the person who wants to use, study, modify, or build upon the software, **an open license**. What it adds - and what disqualifies it in the eyes of the orthodoxy - is two conditions on *who may do what with the original work*\ , not on what the *user* is allowed to do with it. + +The definition being wielded against Reticulum is not even a young one. It is, in essence, the Debian Free Software Guidelines written in 1997, adopted by the OSI in 1998, and treated ever since by certain people as if it had descended from a mountain on tablets. It is an approach that is close to three decades old. Being old is not itself a flaw - but being old is also not a proof of correctness, and the suggestion that the meaning of a word like "open" was settled for all time by a committee in the 1990s, and may never be revisited, is not a position rooted in reason. It is rooted in institutional inertia dressed as principle, maintained by those whose ideologies it serves. + +.. _brandolinis-what-the-argument-is-doing: + +What The Argument Is Actually Doing +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +I would like to go into some detail about the rhetorical mechanism, because it is roughly the same mechanism that powers the rest of the campaign described later in this chapter. + +The orthodoxy's argument is self-referential: *"open source means what we say it means, because we are the ones who define it."* When the Reticulum License is measured against that definition and found wanting, the conclusion is presented as a property of Reticulum - when in fact it is *a property of the definition*. The definition is treated as neutral and authoritative - as some base fact of raw cosmology - and the license is treated as deviant. But the definition is no more neutral than the license is. It encodes a moral position, and that moral position is exactly the one that this project declines to take. + +Consider what the orthodoxy's definition requires, in the case at hand. The OSI-based definition contains, in its ancestry, the Debian Free Software Guideline of "No discrimination against fields of endeavor": The software must not restrict who may use it or for what purpose. Taken to its logical end, this means that open source, properly "certified", must be equally available to those who build hospitals and those who build weapons, those who connect people and those who control them, those who create and those who ingest and replace. + +The orthodoxy presents this as neutrality. It is not neutrality; it is a moral position - one that says, in effect, that *harming human beings is a field of endeavor like any other, and software must not discriminate against it*. + +The Reticulum License takes a different position, and it has the honesty to state it in the license text: this software is for life, not for death; it is for people, not for the systems that would replace them. That is not a restriction on openness, nor on freedom. It is a restriction on *who may consume the work*\ , and it is a restriction the orthodoxy's definition cannot express - which is why the orthodoxy must always attack the license as "not open source" rather than engage with what it actually does. + +.. _brandolinis-who-is-restricted: + +Who Is Restricted By Which License? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The arithmetic is simple, so let's do it out loud, because the orthodoxy's framing inverts it every time. + +The GPL family imposes its conditions on **everyone**\ : You may not distribute, link, or - in the AGPL case - even *communicate with* GPL-covered software without your own work being pulled under the same terms. "Free" in this system is defined (self-referentially) *by the license's own terms*\ ; everything outside those terms is, by definition, unfree. The restriction applies to 100% of users. It applies to the hospital, the mesh community, the school, and the hobbyist with the same force it applies to anyone else. That is not freedom for everyone; it is a *specific moral architecture applied to everyone*\ , presented *as if it were the absence of one*. + +The Reticulum License imposes its conditions on a fraction of would-be users so small as to be practically unmeasurable: + +* Those whose intended use is to build systems that purposefully harm human beings, and +* Those whose intended use is to ingest the work into AI training pipelines. + +That is the entire list. Everyone else - the overwhelming majority, the community, the developers, the users, the downstream projects - receives the full, unrestricted rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, with none of the viral encumbrance of copyleft. + +So when the claim is made that the Reticulum License "is more restrictive" than the GPL, the claim is not merely wrong; it is the exact inverse of the truth. The GPL restricts the freedom of everyone, in the name of a specific ideology. + +The Reticulum License restricts the freedom of the harm-doer and the appropriator, and leaves everyone else free. The two approaches do not differ in whether they contain moral axioms - **all licenses do**. They differ in whether the axioms are stated openly, and in *whose* freedom they restrict. + +.. _brandolinis-consequences-not-open: + +The Consequences Of The "Not Open Source" Claim +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This would be a footnote debate if the mischaracterisation had no practical consequences. It has very large ones, and therefore this section exists. + +The claim that "Reticulum is not open source" is the foundation of the takeover narrative it so often accompanies. The sequence is always the same: + +* First, declare the reference implementation illegitimate ("not really open source", "owned by one man", "not a real community project") +* Second, conclude that it is therefore acceptable - even necessary - to replace it. +* Third, present the replacement, which is (conveniently) often the speaker's own machine-generated clone, as the legitimate heir. + +This is not speculation about motives; it is the documented structure of the campaign examined in :ref:`A Movement Of A Dozen`. + +The "not open source" claim is the legal-ideological battering ram of that campaign. It is recycled, in article after article, in forum after forum, because it works on people who assume that a committee's definition is the same thing as the truth. + +It is also worth stating the other obvious fact: None of these critics have ever shown that the Reticulum License restricts *them*. They do not build weapons. They are not training models on the codebase. They are free, in every practical sense, to use Reticulum exactly as they would under MIT or GPL. Their objection is not to a restriction on themselves; it is to the *mere existence* of a license that states a moral position they disagree with, or which they can use as leverage for a different goal entirely, and to the institutional fact that it does so outside *their* system of approval and control. The complaint is not that the license makes them unfree. The complaint is that the license is *free of them*. + +.. _brandolinis-distribution-argument: + +The Distribution Argument +^^^^^^^^^^^^^^^^^^^^^^^^^ + +A recurring companion claim is that RNS is not properly "distributed", usually deployed as "it's not packaged as a .deb" or "it's not on package manager X", with the implication that it is somehow unavailable or inaccessible, or hard to install on a given system. + +This is simply false, and it has been false for years. The reference implementation is available on practically every platform and architecture with a single command (\ ``pip install rns``\ ). It is packaged in the Arch User Repository, in NixOS, and in a range of other distribution channels, community-maintained and official. It can be installed, updated, and kept current *over Reticulum itself* - the network transports its own software updates. It is used on more than a hundred thousand devices worldwide, is embedded in over a hundred other packages and applications, and carries terabytes of traffic every day. + +The claim that Reticulum needs a ``.deb`` to be "really distributed" mistakes the mechanism for the goal. The goal is that people can obtain and update the software easily, everywhere, **on their own terms**, and distribute it themselves, both offline, online and over Reticulum with full cryptographic verification of the install packages, without any central infrastructure. + +That goal is met to an excellence that few software packages can speak of, and met in a way that does not pin the project's release cadence to the review cycles of distribution maintainers, which is an achievement, not a bug. + +A project like RNS that updates continuously, sometimes daily, and has a track-record of shipping security updates mere hours after issues are discovered, would be crippled by packaging that makes every change wait months for approval. The distribution complaint is a strawman generated for the occasion. It has been answered, in public, many times; it is repeated anyway, because the people repeating it are not counting on facts - they are counting on the reader never having heard the answer. + +.. _brandolinis-on-institutions: + +On The Institutions, In Fairness +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +None of the above is hostility toward the Open Source Initiative or the Free Software Foundation as institutions, nor toward the individuals who have dedicated decades of work to them. Their contribution to the world of software is **enormous**\ , and this document does not dispute it. What is disputed is a specific claim of authority: That "open source" is a term whose meaning is reserved to a committee's approval, and that a license which does not submit itself to that approval is therefore not open. + +That claim of authority is not in Reticulum's interest, and it is not in the interest of the people the movement claims to serve. The current legal and technological landscape - the machine-appropriation of the commons, the weaponisation of "prior work" generation, the erosion of human agency by synthetic systems - was not anticipated by the DFSG of 1997, and the institutions have not, as of this writing, produced *any* meaningful answer to it. The choice, as it was put at the time of the license change, is whether developers should sit back and wait for a solution from a committee that "may or may not ever materialize, before the entire foundation we stand on has been eaten away". + +**Reticulum's answer was to act**. If we had waited, it would have been too late. + +If an OSI-approved license existed that expressed the same constraints - and did not impose the far more severe restrictions of copyleft - the project would have used it. None such exists. That is not Reticulum's failure. It is the measure of what the definition is missing. + +.. _brandolinis-what-open-means: + +What "Open" Means Positively +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For anyone who wants the positive statement rather than the rebuttal, Open Source, in this project's understanding, means: + +* The source code is available, to everyone, without charge +* Everyone may use, copy, modify, merge, publish, distribute, sublicense, and sell the + software +* No one is discriminated against as a person - developer, user, community, or project +* The protocol itself is dedicated to the public domain, where no one can own it +* And the single, plainly stated condition of the license is that the work shall not be + consumed to harm human beings, or ingested to replace the humans who made it + +If that is not "open" by a definition written in the 1990s, then the definition is the thing +that has failed - not the software, and not the people who use it. + +**Open source means open source**. It was true before the committees existed to certify it, and it will remain true after they are gone. + +.. _brandolinis-assistance-versus-substitution: + +Assistance Versus Machine-Substitution +-------------------------------------- + +.. _brandolinis-false-dichotomy: + +False Dichotomy +^^^^^^^^^^^^^^^ + +The public discussion around machine learning and software development has been derailed, by the loudest voices on both sides, into a farcical fight between "AI enthusiasts" and "AI haters". + +.. + + **Both positions are absolute caricatures.** + + **The fight is beside the point in the ways that matters most.** + +It is not an accident, but a very conscious choice that the initial analysis of the Prns case examined herein, and this very chapter, were themself produced with the assistance of a machine-learning based generative system. + +Specifically, it was generated using ``lc`` managing a ``Q8_K_XL`` quant of ``DeepSeek v4 Flash`` running in the ``llama.cpp`` inference engine. The main context base used to stabilize, ground and inform the generative environment consisted of approximately 100,000 tokens of text material that I personally thought out and wrote (by hand), then archived and organized, over the last eight years. + +If you know my writing, and have a hard time discerning where this chapter is me directly, typing manually, and where it is the machine output, it is because of two things: Almost every line in this chapter was either directly edited by my hands on the keyboard or typed by me, and the text corpus that informed the process *is* genuinely me - my thoughts, written by me, over a period of years. + +The chapter was produced this way *deliberately and openly*, under a software framework I designed and wrote, with the human directing the inquiry points, flow of investigation, structure of the outputs, contents of every section, making the editorial decisions, reviewing the conclusions, painstakingly adjusting every line, and taking responsibility for the final claims presented, with the goal of reaching a higher level of synthesis and symbolic density than I could have achieved without that assistance. + +The tool was *used as tool*, both to structure and produce a complex chapter, and to inspect a repository so preposterous in size, commit velocity and nonsensical wording that it barred any purely human inquiry. + +As such, the position is hereby, by personal example and demonstration, stated clearly: + +* **Technological assistance is not the problem** +* **It was never the problem** +* **It is the opposite of the problem** + +The problems are *substitution* and *usurpation*\ : The perverse process in which the machine becomes the author of choices, and the human becomes the facade of software, while expecting "reciprocity" or recognition for deeds they never performed. + +.. _brandolinis-the-line: + +The Line +^^^^^^^^ + +The exact distinction can be reduced neither to how many lines of code a machine produced, nor who pressed the keys. The final distinction has to rest on **who, or what, the real agent of the work is**. + + +* **Assistance** is when the human retains the full seat of agency: The human decides what to build, judges + what is correct, rejects what is wrong, understands what is shipped, and can answer for every single line of it. + The machine writes, suggests, drafts, accelerates *meaningfully* and within reason - but every choice that survives into the + final work is a choice the human made *consciously*\ , and understood - or grew to understand - the consequences of. +* **Substitution** is when the machine *becomes* the agency: the machine decides what to build, + decides what is correct, iterates on its own errors, generates at a scale and speed no single + human can follow - and the human's role is reduced to providing the name, the account, the + signature, and the marketing launch. + +.. + + The Line can be stated as a single test, and this is the same test that has always separated authorship from couriership: **Can the person whose name is on the work answer for it fully?** Not "can they describe what it does" - can they account for why it is the way it is, line by line and decision by decision, and the history of how it came to be that way, under questioning, without machine assistance, including by people who know more than they do? + +If they cannot, they did not author the work. They wore it, or in more severe cases, they stole it. And a courier who claims authorship is not a writer; they are a fraud. + +.. _brandolinis-what-assistance-looks-like: + +What assistance looks like +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Assisted work is recognisable, and recognisability is itself part of its value. It has the following observable properties: + +#. **The human can explain it.** Under examination, the author can say why this choice was + made, what was rejected, and what they verified. The ability to explain is not a luxury; + it is the very demonstration of authorship. On a large project with many contributors this is partial in + practice - no one can explain every line of a large codebase - but the *full capacity* must + exist between the authors and the *habit* must be visible. +#. **The human can, and does, reject machine output.** An author who has never rejected the machine's output is not + an author, but an open drain. Rejection is not a stylistic flourish; it is the + mechanism by which any work attains Quality. A record of decisions, including reversals and rejections, + is a sign of agency. A record without rejection is a record of assent-by-default. +#. **The human's judgment is directional.** The work contains the human's actual choices; + things the machine would not have decided on its own, which the human can defend on their + merits. This directionality has many names in engineering: Design, architecture, taste, + judgment. Where it is absent, the work has the uniform, self-consistent texture of + something that was never doubted, and doubt is exactly what anything important requires. +#. **Provenance is not concealed.** Disclosure of how the work was made is not a legal + requirement in every jurisdiction; it is not even always a practical requirement. But it + is a *statement* that matters. A project that discloses its process - + including its use of machines - is telling the truth about the relationship between the + human and the work, and that is a property users *are* entitled to know. Concealment of + provenance is not a stylistic choice; it is deception, made by someone who knows what the + record would otherwise show. +#. **The human stands behind the failures.** When assisted work fails, the human can say: Yes, I + chose this, under these assumptions, here is why, here is what I got wrong, here is the fix. + That sentence is the entire contract between an author and the people who depend on their work. + A human who cannot say it - because the choices were never theirs - *has nothing to offer anyone*\ , and + is by definition entirely replaceable; anyone else could have pressed the same button. + +.. _brandolinis-what-substitution-looks-like: + +What substitution looks like +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Substitution is equally recognisable, once the pattern is known: + +#. **Scope that no human could have authored.** Output that + structurally cannot have been the product of human authorship, review, and judgment, for + example when the volume exceeds any reasonable human capacity within the span of the project's life. + When the review capacity and the output volume are incommensurable, the output was not + reviewed. It was generated, then forgotten, and the record was signed blindly. +#. **Uniform generation.** The work carries no trace of a human's changing mind. No style + drift, no contested decisions, no "we tried X and it was wrong, so we did Y". That is, *no + signs of actual development, growth and learning*. Instead, endless, self-referential + refactoring, renamed abstractions, and the same fluent register in every commit, + every document, every reply. A human's history shows the wear of judgment. + Pure generation shows the superficial polish of its absence. +#. **Discovery by recursive regeneration.** When errors are found, they are found by the machine's own + subsequent runs, not by human scrutiny - and the findings are recorded as planned + "reviews" and "alignments" rather than as the corrections they are. This is the tell: A + machine editing its own previous output, while the edit is recorded as if it were a + scheduled milestone. That's not review. That's a continuous generation loop revising itself, + with the attempt of an illusion-preserving voice-over. +#. **Laundered provenance.** Theatrical concealment machinery: Commit hooks that refuse + attribution of machine generation, contribution policies that declare machine output + "yours", processes that scrub personal traces from the history, fake identities in the + contributor list. All of these have one function: To make the record say what the "author" + *wished* had happened, rather than what happened. A project that builds such machinery is + not making a record of its work; it is using automated software to manufacture one. +#. **Authorship by assignment.** The human's name is on the work, but the human cannot + answer for it - because the human did not choose any of it, and knows it. The name is not a + signature of authorship; it is a *fraudulent claim of ownership* over something the claimant did not + make and cannot explain. In every field that has ever dealt with such claims - art, + literature, invention, journalism - *this has a name*. That **forgery** is now cheap in software + makes it no more forgivable. + +.. _brandolinis-infrastructure-matters: + +Infrastructure Matters +^^^^^^^^^^^^^^^^^^^^^^ + +For a hobby project, the distinction between assistance and substitution is a personal matter. For infrastructure - code that other people's communications, safety, and freedom run on - it is a matter of life and safety, and any statement about this must be entirely unapologetic. + +Infrastructure has one property that distinguishes it from almost all other software: While most of the people who depend on it cannot verify it themselves, **it must be verifiable, auditable and open to human inspection**\ , and be engineered in such a way that this is as frictionless and straight-forward as possible. + +The reference implementation of Reticulum was designed this way, and continues to make that goal a primary one. While it *is* a complex piece of software, with an intricate array of interlocking and moving parts, the core parts of RNS, the entire Reticulum protocol implementation, the transport logic, the cryptographic primitive interfaces, **is less than 15,000 lines of code**. That line count even includes the rather extensive comments, incredibly detailed logging facilities and other choices that makes the code easy to read and understand for humans, and easy to operate, verify and debug. It took real dedication, and *a lot* of hard work to achieve that. + +Exactly because not *everyone* can do this, it is a fundamental necessity for infrastructure software that it is designed and authored so that *as many as possible can*\ , and that the *chain of accountability* - who made it, who reviewed it, who answers for it - is held intact at every link. That chain is not decoration. It is the entire mechanism by which normal users decide to trust a system they cannot fully verify. The transparent foundations and the chain combined *is* the verification for most users. + +Substitution breaks the chain both at the foundations, and at its load-bearing link: The human at the top can no longer answer, because they were never the maker. Unfortunately, the chain does not always fail visibly; often it fails silently, at the exact moment a question goes deep, or when routing fails subtly at a critical moment. + +For the user, the result is not a project with a normal and humanly flawed author - it is a project *with no author at all*\ ; a signature with no substance behind it, a name that cannot be held to account, and a body of work that nobody on earth can (or wants to) explain, defend, or fix in a crisis. + +.. _brandolinis-the-fluency-trap: + +The Fluency Trap +^^^^^^^^^^^^^^^^ + +It is worth understanding, briefly, why substitution is so attractive and so dangerous at once. Machine-generated output is fluent. It is confident, well-structured, and terminologically *self-consistent*. At the surface, and from the perspective of someone outside a given craft, it is indistinguishable from the output of a knowledgeable human. Fluency of this kind can be a useful property: It makes assisted work fast. But fluency is *not* understanding. It is the *minimal conformal surface* of understanding. + +The danger is that the surface is exclusively where the substituter invests; for the simple reason that the surface is where most of the desired audience looks, and what yields attention to the project. + +A human who can tell the difference uses the tool well. A human who cannot is being deceived through means they cannot detect from inside, namely through their own inability to account for the limits imposed by what they do not know. + +This is why the most important quality for anyone working with systems like Reticulum is not speed, and not vocabulary, but the oldest engineering virtue there is: The honest, uncomfortable, terrorizing knowledge of **what you do not know**. The substitute *never* has it. The substitute's operator, *if* they ever had it, loses it precisely the moment they accept the fantasy of the substitution process. + +The tool is not the hazard, plain old human nature is. The tool is a mirror, and mirrors - as has been observed for rather longer than software has existed - show the truth only to those willing and yearning to see their own shortcomings. + +.. _brandolinis-disclosed-assistance: + +Disclosed Assistance Or Laundered Generation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The contrast at the centre of this entire discussion can be made clearer with two examples, both of which are publicly accessible, both produced in the same year, by people using the same class of tools. + +The first is this chapter. It was produced with machine assistance, openly: the structure was directed by the human, the material was assembled with the tool's help, every conclusion, every line, every slight nuance of meaning and semantics was examined, edited, and accepted or rejected by the human, and the process described publicly - including the precise characteristics of the technological assistance framework used. The human can answer for every claim in these documents, because the human made the decisions the claims rest on. + +The second is the project examined in :ref:`the Prns case`. It was produced by a machine, at a volume no human could review, and the authorship record was engineered to erase the machine's role: A commit hook that refuses attribution of machine generation, a contribution policy declaring machine output the human's own, a fictitious contributor identity, 637,000 lines of unreviewed code. The human cannot answer for the code, because the choices were never made by a human - only the conformal surface of the presentation was. + +The same tool class. The same technology. Two diametrically opposed relationships to truth and responsibility. **The difference is not the tool**. The difference is the presence or absence of the human as the agent of the work - and the honesty or concealment with which that relationship is recorded. + +Assistance leaves the human as the agent and the commons as the source from which the human works and can grow. Substitution removes the human from the loop and converts the commons into fuel for the thing that seeks to replace them, or usurp their work for the profit of the few, human atrophying in the process. + +.. _brandolinis-license-in-context: + +The License In This Context +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Reticulum License, examined in :ref:`What The Reticulum License Is`, draws the same line, at the level of the law. Its AI condition does not forbid the use of machine-learning technology to *assist* development - no reading of the license could support that, and no one associated with this project has ever claimed so. What the condition forbids is the *appropriation of the work into the machine itself*\ : The ingestion of the commons as raw material for synthetic replacement, and the concealed fabrication of "prior work" that would bury the real thing. + +As also noted in :ref:`Copyright & The Two Legal Layers`, plain old copyright law already protects against the case where a process copies the reference implementation into a machine, produces a transformed derivative, and then claims "Copyright, [name of the process operator]", with no human able to account for the creative decisions in the result. That is simple, petty theft, as it always has been. + +.. _brandolinis-general-principle: + +The General Principle +^^^^^^^^^^^^^^^^^^^^^ + +In these regards, the position of this project can be codensed to something relatively concise: + +* Machine assistance in human learning, development, and creation is accepted and useful. + It is not a shameful secret; but it *is* a tool that needs knowledge, training, understanding, + and great care to use. It should not make anything easier or more fun, it should make the + results better, more carefully considered, and arrive at *higher levels of synthesis*\ , not + produce endless streams of code churn. +* The line is crossed when the human stops being the agent of the work. When *any* output is + accepted that the human cannot explain, produced at a scale the human cannot review, or filed under a record + where the human has arranged to conceal the fact. +* The line is crossed, when a human claims authorship of work they cannot + answer for or has usurped. Credit follows the ability to answer. It has always worked that way, and + machines do not change the rule - they only make it cheaper and more tempting to break. +* The people who depend on infrastructure have the right to know which side of the line + the code they run was made on. That knowledge is the only verification most of + them will ever be able to perform. + +Use assistance, by all means, *and learn*\ , but don't substitute. And never sign what you cannot answer for. + +Somewhere, within the general shape of the conceptual framework outlined in this section, or realistically, a more refined variant of it, I do believe there is the *potential* of the *beginning* of a constructive outcome to the immense challenge we are faced with as a species in regards to these problems. + +At the same time, I reserve my right to revert that position to Butlerian Jihad without prior notice. We are on a knife's edge, and you know it just as well as I do. + +.. _brandolinis-void-grants: + +Void Grants: Legal Foundations of Machine-Generated Code +-------------------------------------------------------- + +A grant of rights is only as real as the rights behind it. A license conveys what its issuer holds, and nothing more. A derivative may be distributed only under whatever license covers what it took. And over a work that a machine originated, no human holds anything at all. + +Each of these statements is a matter of settled statute and case law, and this section sets out the authorities. The conclusions they support are: + +#. A software implementation generated from a licensed work by a machine, published under its operator's claimed copyright and license, **conveys rights the operator never possessed**. +#. **Its grant is void**. The projects, products, and promises built upon such grants stand on nothing. A field of void grants is a minefield for everyone who crosses it. + +This section is a general examination of copyright law as it applies to machine-generated code. It is not legal advice. + +I. The Foundational Statute: Translation Is Copying +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The starting point is the statutory definition of the class of works at issue. Title 17, United States Code, section 101 provides the definition of a derivative work: + +.. + + A "derivative work" is a work based upon one or more preexisting works, such as a *translation*\ , musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or *any other form in which a work may be recast, transformed, or adapted*. + + +Section 101 further provides that *"the terms 'including' and 'such as' are illustrative and not limitative"*. As such, the list is a list of *examples*\ , and the very first example is translation. The definition also reaches, in its own words, *"any other form in which a work may be recast, transformed, or adapted"*. + +The exclusive right at issue is defined in section 106: + +.. + + Subject to sections 107 through 122, the owner of copyright under this title has the exclusive rights to do and to authorize any of the following: + (1) to reproduce the copyrighted work in copies or phonorecords; + (2) to prepare derivative works based upon the copyrighted work; + (3) to distribute copies or phonorecords of the copyrighted work to the public by sale or other transfer of ownership, or by rental, lease, or lending; + + +Violation of any of these rights is infringement. 17 U.S.C. § 501(a). + +Taken together, the provisions yield a construction that is difficult to improve upon and impossible to escape: + +#. **A port is a translation.** A work that takes a program written in one language and from it produces a program written in another language, implementing the same behavior, is a translation of the original - whatever mechanism performed it, and however the surface presentation differs. +#. **A translation is a derivative work.** Section 101 says so, explicitly. +#. **Preparing a derivative work is the copyright owner's exclusive right.** Section 106(2) says so explicitly. A derivative work prepared without authorization, or outside the scope of any authorization, infringes that right. + +The common objection - "the code is in a different language, so it is completely different" - is not a legal argument; it is the definition of what the statute already classifies. + +Translation *is the paradigm* of derivative authorship, not an exception to it. If translating a work without permission was a defense, the derivative-work right would be meaningless; every infringing adaptation would simply need to be "different enough" to count as a translation of its source. + +Nor does the identity of the translator change the analysis. The statute asks whether the work is "based upon" a preexisting work. It does not ask who or what performed the translation. A machine that ingests a licensed work and reproduces a translated transformation of it has performed mechanical translation; the output is a derivative of the ingested work, and the law governing derivative works applies to it exactly as it applies to a translation made by hand. + +II. Ideas Are Free, Expressions Protected +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The second foundation is the distinction between what a work *is* - its ideas, its processes, its systems - and the *expression* in which those ideas are embodied. The distinction is codified in section 102(b): + +.. + + In no case does copyright protection for an original work of authorship extend to any idea, procedure, process, system, method of operation, concept, principle, or discovery, regardless of the form in which it is described, explained, illustrated, or embodied in such work. + + +The principle is older than the statute, and its application to software is settled. An author may own the particular code in which a method is expressed; the method itself, the process, the algorithm, belongs to no one - because *"the sine qua non of copyright is originality"* (\ *Feist Publications, Inc. v. Rural Telephone Service Co.*\ , 499 U.S. 340, 345. 1991). And ideas are not original to anyone in particular, *Baker v. Selden*\ , 101 U.S. 99 (1879), established the line: Copyright in a book describing a system does not prevent others from practicing the system. + +Applied to a communications protocol, the structure is clean: + +---- + +**An implementation of a public-domain protocol, honestly reasoned and written by humans, is welcome and unencumbered, and owes nothing to any license. An implementation generated from a licensed implementation is a derivative of licensed work, subject to its conditions and to the ordinary copyright of its source.** + +---- + +The public-domain status of the protocol's ideas changes nothing about the copyright in an implementation's expression. A person who copies an implementation - by machine or by hand - cannot defend the copying by pointing to the protocol, because the protocol covers the ideas, not the symbols in which someone expressed them. + +A further misconception can be dismissed here; the recently popularized "clean-room" claim about the absence of copying. A :ref:`clean-room` is a not a magic label achievable by LLM, but a specific, institutionalized procedure for proving to a court that copying did not occur: Physically separated teams, written functional specifications, attestable non-exposure, and no access to the original by the implementers (\ *Altai*\ , 982 F.2d at 709–11). + +*"I created a clean-room implementation by feeding the original source code into a machine"* attempts to *claim* the certified, legally established procedure for proving the absence of copying by describing, in the same breath, a process **composed entirely of copying**. The word is deployed because the procedure it names is what the claimant would *need to have happened*. + +III. Machine Output Has No Author +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The third foundation is the human authorship requirement. It is settled at both levels of the federal courts and in the Copyright Office's administering practice. + +In *Thaler v. Perlmutter*\ , the district court held that *"copyright law protects only works of human creation,"* and that *"human authorship is a bedrock requirement of copyright"* (687 F. Supp. 3d 140, 146, D.D.C. 2023). On appeal, the United States Court of Appeals for the District of Columbia Circuit affirmed, holding that the Copyright Act *"requires all eligible works to be authored in the first instance by a human being"* (No. 23-5233, D.C. Cir. Mar. 18, 2025). + +The requirement traces to the ordinary meaning of the statutory term. In *Burrow-Giles Lithographic Co. v. Sarony*\ , the Supreme Court defined an "author" as *"he to whom anything owes its origin; originator; maker; one who completes a work of science or literature"* (111 U.S. 53, 57–58, 1884), and more recently described the author as *"the person who translates an idea into a fixed, tangible expression entitled to copyright protection"* (\ *Community for Creative Non-Violence v. Reid*\ , 490 U.S. 730, 737, 1989). + +---- + +**A machine does not owe expression its origin; it reproduces it. No court has recognized copyright in material created by non-humans, and the courts that have addressed the question have rejected it. If you create by machine generation, you do not own the output.** + +---- + +The Copyright Office's registration guidance applies the requirement to generative systems in terms that are directly on point. The Office asks: + +.. + + whether the "work" is basically one of human authorship, with the computer [or other device] merely being an assisting instrument, or whether the traditional elements of authorship in the work (literary, artistic, or musical expression or elements of selection, arrangement, etc.) were actually conceived and executed not by man but by a machine. + + + +* *Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence*\ , 88 Fed. Reg. 16190, 16192 (Mar. 16, 2023) + +And it states the consequence: *"If a work's traditional elements of authorship were produced by a machine, the work lacks human authorship and the Office will not register it"* (\ *Id.*\ ). + +On the role of prompts, the Office is equally explicit: when a system receives a prompt and produces a work in response, *"these prompts function more like instructions to a commissioned artist - they identify what the prompter wishes to have depicted, but the machine determines how those instructions are implemented in its output"* (\ *Id.*\ ). + +The agency applied this standard and excluded machine-originated material from registration in the leading administrative case. In *Zarya of the Dawn* (Cancellation Decision, Feb. 21, 2023, Registration No. VAu001480196), the Office cancelled registration of images generated by the Midjourney service, holding that *"it was Midjourney-not [the author]-that originated the 'traditional elements of authorship' in the images"*\ , while preserving protection for the human-authored text and the human selection and arrangement of the work. + +The Copyright Office's 2025 report on AI copyrightability reaches the same conclusion: + +.. + + Based on the functioning of current generally available technology, prompts do not alone provide sufficient control. + + + +* U.S. Copyright Office, *Copyright and Artificial Intelligence, Part 2: Copyrightability*\ , at iii (Jan. 29, 2025) + +The report's analysis is explicit: *"The Office concludes that, given current generally available technology, prompts alone do not provide sufficient human control to make users of an AI system the authors of the output. Prompts essentially function as instructions that convey unprotectible ideas"* (\ *Id.* at 18). + +Its guiding distinction is stated plainly: *"The use of AI tools to assist rather than stand in for human creativity does not affect the availability of copyright protection for the output"* while *"Copyright does not extend to purely AI-generated material, or material where there is insufficient human control over the expressive elements"* (\ *Id.* at iii). + +The boundary is therefore not "AI or no AI". It is *assistance or substitution*\ : Whether a human exercised sufficient creative control over the expressive elements and can answer for them, or whether the machine originated them and the human merely supplied instructions and a signature. That is a question of fact in each case, determined from the record of how the work was made. + +Two facts follow, and stated together, they form the base legal reality: + + +#. **A work whose expressive elements were originated by a machine contains no valid new copyright: It has no human author. To the extent that the same work reproduces a preexisting copyrighted work without explicit license, it is at the same time an unauthorized derivative. It is unowned for anything new it contains, and unlicensed for everything taken.** +#. **Its operator therefore holds no copyright in it and no grant over it - and a person who holds neither copyright nor grant can convey neither.** + +The first fact makes the work **unownable** by its operator. The second makes it infringing against its source. Neither replaces the other: + + +* The absence of copyright in machine output does not make the output free for anyone to take; it makes it unowned. +* This is a different thing entirely, especially when what it contains is someone else's expression. + +IV. License Conditions Bound the Grant +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The fourth foundation governs what a license *is*. A copyright owner may grant permission to use the work on conditions. The conditions define the scope of the permission. Use outside the scope is use that was never authorized. + +In *Jacobsen v. Katzer*\ , 535 F.3d 1373 (Fed. Cir. 2008), the Federal Circuit held that the conditions of an open-source license are *conditions of the copyright license itself*\ , not mere contractual promises, and that a licensee operating outside them is an infringer: + +.. + + Copyright holders who engage in open source licensing have the right to control the modification and distribution of copyrighted material. + + The choice to exact consideration in the form of compliance with the open source requirements of disclosure and explanation of changes, rather than as a dollar-denominated fee, is entitled to no less legal recognition. + + It is outside the scope of the [license] to modify and distribute the copyrighted materials without copyright notices and a tracking of modifications from the original computer files. + + + +* *Id.* at 1381–82 + +The doctrinal mechanism is settled: *"A copyright owner who grants a nonexclusive license to use his copyrighted material waives his right to sue the licensee for copyright infringement"* within the scope of the license. If, however *"the licensee acts outside the scope, the licensor can bring an action for copyright infringement"*\ : An act outside the granted scope **is infringement** (\ *Sun Microsystems, Inc. v. Microsoft Corp.*\ , 188 F.3d 1115, 1121, 9th Cir. 1999; *Graham v. James*\ , 144 F.3d 229, 236, 2d Cir. 1998; *S.O.S., Inc. v. Payday, Inc.*\ , 886 F.2d 1081, 1087, 9th Cir. 1989). + +Whether a given license term is a condition of the grant or a mere covenant is determined from the license's own language; conditions that limit what may be copied, modified, and distributed - the attribution terms, the notice terms, the modification-tracking terms, the field-of-use terms - are the boundaries of the copyright grant (\ *MDY Industries, LLC v. Blizzard Entertainment, Inc.*\ , 629 F.3d 928, 940, 9th Cir. 2010). + +Three consequences follow for the analysis at hand. They are not hypothetical. + +**First, the conditions are measured at the moment of copying** + +A work is licensed under whatever conditions applied when the reproduction, adaptation, and distribution occurred. There is **no** period in which copying a licensed work is "free" because the copy was made by a machine; the machine is the *licensee's tool*\ , and the licensee is bound by the conditions regardless. A derivative generated without satisfying the conditions - without the attribution, without authorization for the manner of use - was never within the scope of the license, from the first instant of its existence. + +**Second, breach does not restore rights that never attached** + +The district court in *Artifex Software, Inc. v. Hancom, Inc.*\ , No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017), analyzing the GPL's termination provisions, observed that *"the language of the GPL suggests that [the licensee's] obligations persisted beyond termination of its rights to propagate software using Ghostscript,"* because the source-code obligation recurs each time a covered work is conveyed. The same structure operates a fortiori where a derivative was produced *outside* the license entirely: No grant ever attached, and no subsequent event creates one. + +**Third, the settled conditions are the enforceable core** + +The attribution and notice conditions rest on the settled doctrine above. Novel conditions (restrictions on field of use, restrictions on how the work may be consumed) are enforceable as conditions of the grant when clearly drafted, but their enforcement history is thinner. The argument that a derivative is unlicensed does *not* depend on the novel conditions being vindicated; it needs **only** the settled ones, and the ordinary law of derivative works, to stand. + +V. The Void Grant +^^^^^^^^^^^^^^^^^ + +The preceding sections assemble into a single structure. Let us apply it to an example situation: + + +* A project presented as an independent implementation of a protocol; "ground-up", "from scratch" or "clean-room" work. +* The actual history shows continuous, machine-mediated ingestion of a licensed reference implementation. +* The output is generated at a scale no human could produce or review, with the provenance of the process obscured. + +**Step One: The derivative** + +The project's output is a translation of the licensed implementation: A derivative work, produced by a copy process. 17 U.S.C. §§ 101, 106(2). Preparing it without authorization infringed from the first moment of its existence. *Id.* § 501(a). + +**Step Two: The license** + +The derivative was produced outside the conditions of the license; without the notices, without the attribution. The license never attached (\ *Jacobsen*\ , 535 F.3d at 1381–82). + +**Step Three: Authorship** + +The expression was originated by a machine. No human can account for its creative decisions, and no human authored it. It contains no valid new copyright (\ *Thaler*\ , 687 F. Supp. 3d at 146; No. 23-5233, D.C. Cir. 2025; 88 Fed. Reg. at 16192). + +**Consequence: Void Grant** + +The statute supplies the consequence. Section 103(a) provides: + +.. + + The subject matter of copyright as specified by section 102 includes compilations and derivative works, but protection for a work employing preexisting material in which copyright subsists does not extend to any part of the work in which such material has been used unlawfully. + + +And section 103(b) provides that copyright in a derivative work *"extends only to the material contributed by the author of such work."* The legislative history states the point without ambiguity: *"An unauthorized translation of a novel could not be copyrighted at all"* (H.R. Rep. No. 94-1476, at 57, 1976). + +In our example, the operator of the derivative's copy process decides to assert copyright over the output, and licenses it to the world under terms of the operator's choosing, for example the Apache License. + +But the operator holds no copyright in machine-originated content (section III) and no license over the source from which it was derived (sections I and IV). + +For the derived material, the operator's copyright claim **is an assertion of a right that never existed**. The material was used unlawfully, and section 103(a) withholds protection from *every* part of the work in which it appears. For the machine-originated remainder, the operator holds no copyright either, for lack of any human author. + +The operator's license to the world is a promise the operator had no power to make. Every person who receives the work believing they received a valid grant has received **a void grant**\ , and stands, as a matter of settled law, in the position of a downstream user of an unauthorized derivative, whatever they were told at the time. + +This is a cascading consequence, and it is why the pattern is a hazard. No combination of self-granted licenses - "MIT," "Apache," "public domain," anything at all - can transfer rights the operator never held. Every downstream project, product, or deployment built on the derivative is built on unlicensed reproduction of a third party's work, whether or not it knew, whether or not it was told, and whether or not the marketing was plausible. + +The longer the derivative circulates unexamined, the more it becomes embedded, forked, vendored, depended upon, and the more expensive its correction becomes for everyone who trusted it. A field of superficially real projects, repositories, and licenses that **in reality confer nothing on anyone who relies on them is a minefield**\ , in the most precise sense the law allows: The rights they purport to grant *were never possessed*. + +The law defines what may be asserted, not what will be. The copyright owner may choose whether and how to assert these rights, and at what point in time. The exposure exists regardless, and for *every* downstream that trusted the void grant. This is the scope of the hazard that the conduct exemplified here produces. + +VI. Fair Use Does Not Rescue This Pattern +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Every defendant raises fair use. It is an essential and important limitation in the service of free speech, accountability, criticism, education and other important domains. Therefore, it must be considered, and in the case exemplified here, it fails. + +Fair use is a limitation on the exclusive rights, evaluated case by case under four factors: The purpose and character of the use; the nature of the copyrighted work; the amount and substantiality of the portion used; and the effect of the use on the potential market for or value of the work (17 U.S.C. § 107). + +On the first factor, the governing standard is *Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith*\ , 598 U.S. 508 (2023), in which the Supreme Court held that: + +.. + + In sum, the first fair use factor considers whether the use of a copyrighted work has a further purpose or different character, which is a matter of degree, and the degree of difference must be balanced against the commercial nature of the use + + +The question is whether the use serves a further purpose, not whether the surface changed. A derivative that exists to serve as the same thing as the original, marketed to the people who would otherwise use the original, has not acquired a further purpose by being translated; the surface changed, the function did not, and the use is commercial. + +The remaining factors resolve the same way. Source code is expressive creative work, not bare fact. The pattern under examination copies the whole; a complete implementation, ingested and translated in its entirety. And the market effect is the decisive factor, because it is engineered: A derivative marketed as a drop-in replacement for the work it was copied from is not a complement to the original's market, it is a substitute for it. The Supreme Court has long held that use of a work to satisfy the market demand for the original is the paradigm of an *unfair* use (\ *Harper & Row, Publishers, Inc. v. Nation Enterprises*\ , 471 U.S. 539, 566–67, 1985). + +The one case that is always raised in response, *Google LLC v. Oracle America, Inc.*\ , 593 U.S. 1 (2021), holds less than it is believed to. The Court there assumed *"for argument's sake, that the material was copyrightable"* and held *"that the copying here at issue nonetheless constituted a fair use"* (\ *Id.* at 11). + +The material in question was a thin slice of *declaring code*\ , which the Court found sits, *"if copyrightable at all, further than are most computer programs (such as the implementing code) from the core of copyright"* (\ *id.*\ ), in a use that built a new platform for a new environment, with the copier **having written the vast majority of its own code**. By comparison: A wholesale translation of an entire implementation, marketed as a substitute for it, is **not** that case; it is the other end of every factor. + +The valuable zones of fair use remain, and they are important. **Commentary and criticism**\ , quoting from a work to review, discuss or criticize it. **Teaching and scholarship**\ , explaining concepts and quoting excerpts, is its traditional beneficiary. + +Conclusion +^^^^^^^^^^ + +The law is neither obscure nor new. The conclusion it yields can now be stated: + + +* A machine translation of a protected implementation **is a derivative work**, and an unauthorized derivative **is an infringement**, whatever language it speaks and whatever machinery produced it. +* A work whose expression a machine originated has no human author, no valid new copyright, and without valid copyright **no license can be granted on it**. +* § 103 withholds protection from every part of a derivative in which protected material was used unlawfully. A license is a grant with conditions, and a derivative made outside the conditions **never received a grant**. +* A person who holds no copyright and no grant **can convey neither**, and *every* downstream consumer who received from them received a **void grant**. + +This is a *catastrophic* failure state for all who want to create things good and useful: The projects that inherit only void grants and liability believing they have inherited foundations, the users who depend on code that no one on earth can answer for, the honest builders whose work is buried under a field of plausible-looking impostors. + +Sources and Authorities +^^^^^^^^^^^^^^^^^^^^^^^ + +Statutory references are to Title 17, United States Code. Case citations are to the official or generally cited reporters. Online links are for reference only. Section numbers refer to the sections in which each authority is principally relied upon. + +**Statutes** + + +* `17 U.S.C. § 101 (definitions: "derivative work," "including," "publication") - I, II `_ +* `17 U.S.C. § 102(b) (idea/expression) - II `_ +* `17 U.S.C. § 103(a)–(b) (derivative works employing unlawfully used preexisting material) - V `_ +* `17 U.S.C. § 106(1)–(3) (exclusive rights: reproduction, derivative works, distribution) - I `_ +* `17 U.S.C. § 107 (fair use) - VI `_ +* `17 U.S.C. § 501(a) (infringement) - I, V `_ + +**Judicial decisions** + + +* `\ *Jacobsen v. Katzer*\ , 535 F.3d 1373 (Fed. Cir. 2008) - IV, V `_ +* `\ *Sun Microsystems, Inc. v. Microsoft Corp.*\ , 188 F.3d 1115 (9th Cir. 1999) - IV `_ +* `\ *Graham v. James*\ , 144 F.3d 229 (2d Cir. 1998) - IV `_ +* `\ *S.O.S., Inc. v. Payday, Inc.*\ , 886 F.2d 1081 (9th Cir. 1989) - IV `_ +* `\ *MDY Industries, LLC v. Blizzard Entertainment, Inc.*\ , 629 F.3d 928 (9th Cir. 2010) - IV `_ +* `\ *Artifex Software, Inc. v. Hancom, Inc.*\ , No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017) (settled; dismissed with prejudice Jan. 2018) - IV `_ +* `\ *Thaler v. Perlmutter*\ , 687 F. Supp. 3d 140 (D.D.C. 2023), aff'd, No. 23-5233 (D.C. Cir. Mar. 18, 2025) - III, V `_ +* `\ *Burrow-Giles Lithographic Co. v. Sarony*\ , 111 U.S. 53 (1884) - III `_ +* `\ *Community for Creative Non-Violence v. Reid*\ , 490 U.S. 730 (1989) - III `_ +* `\ *Feist Publications, Inc. v. Rural Telephone Service Co.*\ , 499 U.S. 340 (1991) - II `_ +* `\ *Baker v. Selden*\ , 101 U.S. 99 (1879) - II `_ +* `\ *Computer Associates International, Inc. v. Altai, Inc.*\ , 982 F.2d 693 (2d Cir. 1992) - II `_ +* `\ *Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith*\ , 598 U.S. 508 (2023) - VI `_ +* `\ *Google LLC v. Oracle America, Inc.*\ , 593 U.S. 1 (2021) - VI `_ +* `\ *Harper & Row, Publishers, Inc. v. Nation Enterprises*\ , 471 U.S. 539 (1985) - VI `_ + +**Administrative and policy authorities** + + +* `\ *Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence*\ , 88 Fed. Reg. 16190 (Mar. 16, 2023) - III `_ +* `\ *Zarya of the Dawn*\ , U.S. Copyright Office (Cancellation Decision, Feb. 21, 2023), Registration No. VAu001480196 - III `_ +* `U.S. Copyright Office, *Copyright and Artificial Intelligence, Part 2: Copyrightability* (Jan. 29, 2025) - III `_ +* `H.R. Rep. No. 94-1476 (1976) - V `_ + +.. _brandolinis-evaluating: + +Evaluating a Reticulum Implementation +------------------------------------- + +.. _brandolinis-intention-of-guide: + +The Intention Of This Guide +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Very few user of network infrastructure can verify the software they run. This is true of the reference implementation as well, and it is precisely why it was engineered the way it was: the entire Reticulum protocol implementation - the transport logic, the cryptographic interfaces, the routing - is less than 15,000 lines of code, including its extensive comments and detailed logging. The reference is *designed* to be readable by a human in a reasonable sitting. That is a deliberate decision, and it is the standard against which every other implementation should be measured: An implementation that asks for trust while being structurally unreadable is asking for the absurd. + +Because most users cannot verify the code directly, the evaluation of the *project* is the evaluation of the software. The framework below exists so that this evaluation can be performed in minutes, by anyone, without expertise - and so that each new "implementation" does not require the kind of full investigation that would otherwise be if not impossible, prohibitevly expensive. + +.. _brandolinis-two-questions: + +Two Questions That Resolve Most Cases +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Other considerations in this guide is further corroboration. These two questions allow you to decide the case quickly in most instances, and they should be asked first. + +**Question 1: Does this speak the protocol, or was it just generated from the reference?** + +The copyright and license realities, described in :ref:`What The Reticulum License Is`, is the legal foundation of this distinction. The protocol is public domain: A *genuine* :ref:`clean-room` implementation, reasoned out and written by humans, is free and welcome, and owes nothing to any license. But an implementation that was *directly generated from* the reference - reproduced by a copy process, whether manually or through a machine or software - is a derivative of the licensed work, and is subject to both the license's conditions, and to the ordinary copyright law examined in :ref:`Copyright & The Two Legal Layers`. A primarily machine-generated copy without substantial human creative input is not merely unlicensed; it is a copyright violation that would exist under any license at all. + +**Ask**: Does the project say where its protocol knowledge came from? Does it credit the reference implementation, or claim "ground-up" status while its own history shows continuous ingestion of the reference's source? Does its license carry the original copyright notice? The answers tell you, within minutes, which of two very different kinds of project you are dealing with. + +**Question 2: Who, or what, is the agent of the work?** + +This distinction, established in :ref:`Assistance Versus Machine Substitution`, is the trust foundation of everything else. Is there a human who decided what to build, judged what was correct, rejected what was wrong, understands what was shipped - and can answer for it, line by line and decision by decision, *without machine assistance*\ ? Or is the machine the agent, with the human's role reduced to the name, the account, and the signature? + +.. + + This test has a sharper form: **would the project be meaningfully different if someone else had pressed the button?** If the answer is no - if any person could have been the signature and nothing would change - then the "author" is not the agent of the work. They are its facade, and the project is, in the most literal sense, worthless and unowned. + +A project with no owner is a project no one can answer for, and infrastructure with no one to answer for it has no place carrying other people's traffic. + +.. _brandolinis-other-signals: + +Other Signals To Look For +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Once the first two questions are answered, the following signals determine the verdict. None is alone decisive; together they form a pattern that is difficult to fake in the directions that matter. + +.. _brandolinis-provenance: + +Provenance and attribution +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* **Credit to the reference.** Does the project name Reticulum's reference implementation + in its README, its website, its licenses, and the code? Does it present itself as a port + or as a "ground-up" origin story? Absence of credit, in a field where every implementation + owes its existence to the reference, is not an oversight; it is a decision. +* **License compliance.** For a derivative, the license conditions apply: the copyright + notice and permission notice in all copies and substantial portions, the harm condition, + the AI-training condition. A project whose license file claims a fresh copyright in the + operator's name, over work that was generated from the reference, has failed the minimum + bar of honesty before any code is read. +* **Disclosed provenance.** Is the use of machine assistance stated openly, or does the + project maintain machinery to conceal it - commit hooks that refuse attribution of + generation, contribution policies that declare machine output the human's own, scrubbers + for personal traces, fictitious contributor identities? The first is the mark of a human + using a tool. The second is the mark of a record being manufactured. +* **The author's history.** Is there a prior record - projects, contributions, a body of + work that a person can look at and reasonably assess? A sudden, fully-formed "decade of experience" + appearing from nowhere, attached to a project of unprecedented scope, is a story that + contradicts itself. + +.. _brandolinis-agency: + +Agency and answerability +~~~~~~~~~~~~~~~~~~~~~~~~ + +* **Who answers the questions?** When technical questions are asked, does a human answer + with substance - going deeper, explaining trade-offs, admitting uncertainty - or do + answers deflect to process ("the CI verifies it", "the proofs prove it", "the audit + covered it")? Are the answers themself machine generated? Deflection to process is + the substitute's answer pattern: It names the machinery instead of the reasoning. +* **Velocity commensurate with authorship.** Is the output volume compatible with human + authorship, review, and judgment? An implementation ten (or 42!) times the size of the reference, + produced in a fraction of the time by a single person, is not evidence of brilliance; it + is evidence of unchecked generation. Churn is part of the same signal: A project that + deletes half of everything it adds is not building; it is looping. +* **Signs of development, growth and learning.** Do reversals exist? Contested decisions? + "We tried X and it was wrong, so we did Y"? Humans change their minds, admit mistakes, and + leave the wear of judgment in their history. Pure generation shows "the polish of its + absence": uniform register, endless renaming, and errors discovered by the generator's own + later runs, recorded as if they were planned milestones. +* **Standing behind failures.** When something is wrong, does the human say "I chose this, + here is what I got wrong, here is the fix"? Or do corrections arrive as process language, + with nobody accepting that a decision was even made? A project whose history contains no + first-person acceptance of error contains no author. + +.. _brandolinis-engineering: + +Engineering reality +~~~~~~~~~~~~~~~~~~~ + +* **Honest benchmarks, or none.** If performance is claimed, is the baseline real - stock, + current, interpreted RNS, on the modern interface, at equal policy, with methodology + published in advance and reproducible by anyone? +* **Interop with reality.** Is compatibility verified against the *current* reference + implementation - on real hardware, including the radio and serial interfaces this + protocol family lives on - in both directions, over long transfers, uptimes and edge cases? +* **The readability standard.** Can a competent human read the core of this implementation + in a reasonable sitting, the way the 15,000-line reference can be read? Was human + readability a stated design goal, or an afterthought? A project that cannot be inspected + is a project asking for trust it has not earned and will never attend to. +* **Nonstandard inventions.** Does the project "improve" on the protocol with its own + modes - new channel behaviour on shared spectrum, new rendezvous mechanisms, new crypto, + "post-quantum" replacements, "turbo" variants? Inventions that change behaviour on a + shared network are not features; they are forks of the airwaves, imposed on every other + node that shares the medium. A project that invents on top of a protocol it has not yet + correctly implemented is not advanced; it is dangerous to its neighbours. +* **The public record.** The commit history is public. Read it. + +.. _brandolinis-network-citizenship: + +Network citizenship +~~~~~~~~~~~~~~~~~~~ + +* **Honest presence.** Does the project identify itself honestly on the network, or does + it masquerade as something it is not? +* **Coexistence.** Does it respect the shared medium and network conventions? A node that + is a bad neighbour on the spectrum is a hazard regardless of how well its code works in isolation. +* **Community participation.** Does the author participate in the community as a member - + answering questions, contributing, learning - or only appear to advertise? The second is + not participation; it is exploiting the community as a broadcasting target. + +.. _brandolinis-signals: + +Monetary and influence signals +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* **Money under the claim.** Donations, funding, or commercial offers premised on claims + like "89× faster" or "formally proven" convert false marketing into a different category + of problem. When money changes hands on the strength of fabricated measurements, the + stakes are no longer theoretical. +* **Tokens and "investment" vehicles.** Any implementation that surrounds itself with a + crypto token, a "coin", or an investment pitch should be treated as what it is: A project + whose primary purpose is to earn the controller a profit, not open networking. +* **Marketing-first ordering.** A polished website on day three, a twelve-language marketing + presence, a "benchmarks" page and a "get started" funnel existing before the protocol works + is a massive red flag. Real builders ship, then talk. The inverse order is the signature of + a project whose goal is attention. + +.. _brandolinis-conformal-surface: + +The Conformal Surface +^^^^^^^^^^^^^^^^^^^^^ + +One warning before the synthesis. When you evaluate any project, assume - as a working hypothesis - that its surface is an investment. The marketing, the design, the badge collection, the "proof records", the fluent and confident prose: This is exactly where substitution invests, for the simple reason that it is where the audience looks first. Fluency is the *minimal conformal surface* of understanding, and the surface is not evidence of anything except that the author *wanted to look convincing*. If you find yourself impressed by the surface before you have asked Question 1 and Question 2, you are doing the evaluation in the order the substitute operator hoped you would. + +.. _brandolinis-possible-verdicts: + +Possible Verdicts +^^^^^^^^^^^^^^^^^ + +The framework proposed here can yield three different verdicts: + +#. + **Meets the standard.** A named human who can answer for the work and demonstrably does; + provenance disclosed; attribution given; honest benchmarks; interop + demonstrated against current, real RNS on real media; readable code; a maintenance + history that shows growth and learning. This standard is not high. It is what the + reference implementation has met, in public, for over a decade, and it is what any + project that wants other people's traffic should be willing to meet in turn. + +#. + **Experimental, but honest.** A project that clearly labels itself as in-progress and + experimental ("do not use this yet", in plain words, as the first thing a user sees) + discloses its provenance, credits the reference, and is being developed in the open by + humans who answer questions. Such projects should be encouraged. They are how the + ecosystem grows, new ideas are tested, and the framework above is designed to make an + honest experimental project *easy* to recognize, not hard. + +#. + **Does not meet the standard.** Unanswerable authorship, concealed provenance, fabricated + measurements, invented protocol behaviour, absent interop, marketing ahead of substance. + Such projects should be treated as unproven regardless of their surface, and as hazards + if they invite users onto shared networks. The community owes them exactly the + skepticism they have earned, and not a moment of engagement beyond that; the network's + time is better spent elsewhere. + +.. _brandolinis-standards-reasonable: + +These Standards Are Reasonable +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +I'll close this guide by stating what these standards are *not*\ : They are neither a demand for perfection, nor a ban on machine assistance. Assistance is useful, when it is used to arrive at *higher levels of synthesis* than unaided work. It is not a requirement that an implementation be a clone of the reference; neither is it a requirement that it invents everything from scratch or aspires to be a :ref:`"clean-room"` implementation. Good implementations of the protocol are very welcome, *however they come*, but working on one requires *serious* work, considerable skill, and **deep competence**. + +The reference implementation has met this standard for years, and its users know what that looks like. + +.. _brandolinis-movement-of-a-dozen: + +The Movement Of A Dozen +----------------------- + +.. _brandolinis-presentation-elongated: + +Presentation, Elongated +^^^^^^^^^^^^^^^^^^^^^^^ + +Whenever Reticulum defends itself, its license, or its community - or simply continues to exist - a familiar chorus appears. The register is always similar: *concern*. Concern about the direction of the project. Concern about its license. Concern about its governance. Concern about its "bullying" of "good-faith contributors". Concern about the future of the ecosystem at the hands of a single maintainer. The chorus speaks in the plural, presents itself as a body of independent voices, and insists, with some frequency, that it is... *not alone*. + +The implicit claim under examination in this section is that there exists a *movement* of concerned individuals, spread across the ecosystem, all worried about Reticulum, and therefore (for some reason) deserving of a place at the table of decisions. + +A resolution of this claim requires one step: Count them. + +.. _brandolinis-headcount: + +Headcount +^^^^^^^^^ + +This "movement" does have a headcount. It is not in the hundreds, and it is not in the dozens. It is a small number of people who appear, in various combinations and under various names, in the following roles: + +* Creators of the machine-generated "Reticulum implementations" examined in this chapter. +* Creators of articles praising those implementations and lamenting the state of the + reference, its moral shortcomings, its unavailability or lack of something it already has. +* Commenters "defending" the implementations when they are evaluated reasonably and critically, + most often by attempting simply to derail the discussion. +* Critics of the Reticulum License on "open source" grounds. +* "Concerned community members" objecting to the maintainer's conduct. +* Campaigners on online platforms; and +* In some cases, a single individual performing *several* of these roles at once, under + different names, in the same week. + +The overlap is well documented at this point, across time and different platforms. The same phrasing, the same arguments, the same links, the same reactive reflexes, the same handful of accounts appearing in the same threads at the same moments. When the sockpuppets are unmasked (and they frequently unmask themselves) the cast does not grow, but rapidly shrinks. + +This is the most interesting single fact about the "movement": **It isn't one. It is a synthetic cast**, held together mostly by LLM-glue, reddit handles and hysteria. A cast is not a constituency. It performs; it does not represent. The difference matters quite a bit, because a great deal of this "movement's" imagined power comes from the assumption that the *plural form* is actual evidence of plurality. If that sentence seemed opaque, notice how many times a statement or article uses "we" instead of "I", and it will be less so. + +.. _brandolinis-recycled-wine: + +Recycled Wine, Fermenting +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The cast is not only small, it is also, by any evidentiary standard, *forgetful*. Every major claim this "movement" advances has been advanced before, answered in public, with evidence, and often years ago - and is then advanced again, unchanged and completely ignoring any rationale or evidence presented previously (to the same people), as if the answer had never been written. + +* **The license argument.** Reticulum is "not really open source" because its license is not + approved by a particular orthodoxy. This is answered (now in a new and updated version, for the + fifth time) in full in :ref:`Open Source Means Open Source`. It was also + answered in public, at length, at the time of the license change - including the + arithmetic of who is actually restricted by which license. It is repeated *ad infinitum* anyway. + Quite a conversation starter, apparently. +* **The distribution argument.** Reticulum is "not properly distributed" because it is not + packaged as a ``.deb`` or on some favoured catalogue. Reality: It is available on practically every + platform with a single command, packaged by the community in a wide range of channels, and + capable of updating itself over its own network. The argument has been answered; it is repeated. +* **The "stepped back" narrative.** When the primary mirror of the project moved away from + a public internet platform, it was spun as the founder leaving for good, or now taking on dictatorial + powers, or abandoning his creation, or any variation or nonsensical combination thereof. + Those spins always center around justifying that *a vaccuum now needs to be filled*. + There was no such vaccuum. The narrative is repeated in various forms whenever convenient. +* **The enclosure narrative.** The license is reframed as a "power grab" or an "enclosure" + of the commons - as if a license whose protocol is public domain and whose conditions + restrict only harm and appropriation were a form of enclosure. The `most recent `_ (and mostly incoherent) + expression of this narrative is, once again, fluent, polite, and factually hollow. The + bizarre arguments supporting the "article" include: Defunct and abandoned forks presented + as living, community forks bearing the very Reticulum License mislabeled as AGPL license vehicles + (created by "concerned users"), companion app forks correctly retaining the Creative Commons + licensing used as further evidence of the same and completely abandoned projects propped up + as being "the ecosystem". Another case of LLM generated nonsense that the "author" didn't bother checking. + The intent is clear here, simply produce more *mass* of the bullshit, so it can be further + referenced, regurgitated and linked to. +* **The "bullying" narrative.** Whenever the community declines to treat manufactured + controversies as legitimate, or calmly documents the falsity of claims, or (Lord forbid) + moves a forum post for violating clearly stated forum rules, + the response is the same: The documentation is "bullying", the community is "excluding" people, the + maintainer is "unprofessional". In the most recent example, those accusations were made by someone who, in the + same week, publically called for the Reticulum maintainer's "removal from the equation", forged a moderator's + username, attempted to drag unrelated individuals into the campaign, and presented a new + round of outright falsehoods. Contrary to popular belief, the accusation of incivility + is not the last resort of the wronged; it is the standard reflex of the exposed. + +None of the "arguments" engages the answers given repeatedly, and extensively. That is the point, and the strategy. The arguments are not produced for the purpose of being engaged; they are produced for the purpose of *being repeated* - the same wine, poured into new bottles, on a cycle. Each cycle is short, cheap to produce, and (thanks to freely available fluent text generation) now nearly effortless. The intended audience is not the community, which has heard it all before. The intended audience is the newcomer, who has not. + +.. _brandolinis-the-method: + +The Method of Madness +^^^^^^^^^^^^^^^^^^^^^ + +The method behind the pattern is consistent and simple enough to be described precisely: + +**Bullshit asymmetry** + +Producing a fluent, plausibly-sourced smear is now the work of minutes. Refuting it to the standard this manual demands is the work of days, and the refuted smear is replaced by the next one within the week. This asymmetry isn't just a fine point of the campaign; **it is the campaign**. The goal is exhaustion - the slow conversion of the community's time and attention from building to defending. + +**Weaponized concern** + +The register of the campaign is almost always the register of solicitude: "we are worried about the ecosystem", "we just want what is best for the community", "this is about the future of the project". The concern is directed, without exception, at the things the campaign wants changed, and the change it wants is always the same: **The replacement of the reference's authority with its own**. Concern is the *costume*\ ; capture is the choreography. It is the oldest form of cheap power grab in the book. + +**Event seizure** + +Any event - a license change, a platform move, a forum moderation decision, a subreddit closure, a security notice, even the most banal messages from maintainers or known contributors - are seized, stripped of their actual context, and re-narrated as evidence of the same pre-written story. The subreddit that was closed after its moderator vanished and ceased moderating (according to *prior agreement with said moderator*) becomes "the maintainer shutting down dissent". Moving away from a highly centralized online platform becomes "the founder retreating". The license becomes "the enclosure". The pattern is so reliable that the story could be pre-written by a lightly mechanized quill; only the date changes. The actual real-world context of these events is documented, in public, in each case; the re-narration proceeds regardless. + +**The legitimacy circuit** + +The campaign invests heavily in the places where legitimacy is minted: Conference talks, blog platforms, social threads, and forums - presented as if these appearances constituted some sort of ecosystem-wide groundswell rather than the same dozen people moving through the same circuit. The LLM-generated articles cite the LLM-generated ports; the ports are praised in the articles; the managers of the ports spread the articles, and echo them on the forums and internet platforms; the conference presentations cite the forums. Random bypassers with the need for a cause watch the conference presentations and take on the holy duty of Internet Soldier. The circuit is closed, self-referential, and (to a reader encountering it fresh) convincing. It is also, entirely, **a loop of bullshit**. + +**The prior-work minefield** + +The machine-generated implementations have a consequence beyond attention: They flood the space with fake "prior work". The effect, as the license discussion predicted in the beginning of 2025, is the creation of a minefield of sloppy repositories that can later be matched against any genuine project, and attempt to claim prior art, or even worse: Dissuade actual, honest developers or builders from taking up a real project they might have succeeded with, because they now believe it has already been done. Just as importantly, it also buries real efforts under machine-generated noise. The machine-ports are not failed attempts to contribute. They are (disregarding intentions, but effectively) the campaign's long game, deployed as inventory. + +.. _brandolinis-fragile-triad: + +A Persistent, But Fragile Triad +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This chapter as a whole has documented three fronts: The legal-ideological attack on the license (:ref:`Open Source Means Open Source`), the substitution and usurpation pattern in machine-generated implementations (:ref:`Assistance Versus Machine Substitution`), and the takeover narratives examined in this section. They are three fronts of the same operation, run by the same cast. + +* The license attack and other urgency-engineered narratives are the *cover*: They supply + the ideological justification for treating the reference as illegitimate, and needing replacement. +* The ports are the *inventory*: they supply the "replacements" that the narrative claims + the ecosystem needs. +* The takeover narrative is the *objective function*: the repeated, persistent, escalating claim that + the reference should be replaced, and that the speakers themself are the natural heirs. + +Each front depends on the others, and all three depend on a single, fragile assumption: That their audience cannot count. Restore the count, and the charade collapses into what it is: + +**A small group of people, obsessively orbiting a technology they did not build, synthetically producing the +appearance of a constituency they do not have, in service of a takeover they cannot justify.** + +.. _brandolinis-pattern-is-not: + +What The Pattern Is Not +^^^^^^^^^^^^^^^^^^^^^^^ + +It is important, to also say what this pattern is *not*, exactly because the campaign depends on being mistaken for such things. + +**It is not criticism** + +The Reticulum community has always had lively, rigorous criticism - of decisions, of priorities, of direction - and it has always engaged that criticism on the merits, and changed course and development priorities many times. The license discussions at the time of the change were extensive, public, and answered in full, including with the critics themselves. Core protocol decisions were always discussed and evaluated in the community. The complex coordination and execution of several protocol upgrades between a loosely organised group of developers, node operators and users have succeeded surprisingly fluidly. All of these are success stories that the "critics" **always** ignore. Real criticism engages the content and accepts evidence. The campaign engages nothing. + +**It is not a community** + +Communities *build things*, maintain them, and have skin in the game; long-term users, operators of nodes, authors of real applications, people whose traffic flows through the network every day. A community has a stake. The "movement" only has an agenda. + +**It is not a debate** + +A debate has parties who evaluate arguments and evidence, and as a function of that, the debate moves forward, perpetually. The campaign's arguments, as shown above, are not designed to survive contact with answers, but to be repeated past them. You cannot debate a loop. You can decline to perform for it, though. + +.. _brandolinis-intent-and-consequence: + +Intent & Consequence +^^^^^^^^^^^^^^^^^^^^ + +While it would provide for interesting speculation, we do not need to know what the individuals in the cast *intend*, and this document will not speculate about their inner lives. People may believe their own narratives entirely, or partly, or not at all; **the pattern is the same in any case**, and the pattern is what matters here, since it is the exact thing that has been so insidiously destructive and resource wasting for the actual Reticulum project and community, ever since Reticulum was more widely discovered, popularized, and became a prime target for all sorts of grift known to man. + +The consequences are very real: + +* **Time**. The community's scarcest resource is the attention of skilled people who actually build + and maintain the network. The campaign converts that attention into reactive defence, on a cycle + with no end. +* **Harm**. Hastily machine-generated implementations, marketed as drop-in replacements and carrying + traffic onto shared networks, mislead users and can damage the network and its neighbours. + We, the actual reticulum community, all rely on these networks every day, and it is my belief + that we need to defend them. The fabricated measurements and laundered authorship examined in this chapter are not + editorial embellishments; they are the mechanism by which real users are induced to run + unverified, and often destructive software. +* **Erosion of the currency of trust**. Every manufactured scandal, every fluently polite smear, every + fabricated "movement" debases the currency of trust and degrades it for **everyone**; + including, most of all, the honest projects that come after. This is deep harm, and + it is the primary reason this chapter exists. + +Whatever the intent - profit, control, attention, or a simple, obsessive inability to stop - the mechanism is the same, and the response should be *calibrated to the mechanism as a whole*, not to the individual person acting as the current avatar for it. + +.. _brandolinis-recognition-and-response: + +Recognition & Response +^^^^^^^^^^^^^^^^^^^^^^ + +For anyone who encounters the pattern fresh, here is a proposal on how to recognise it, and what to do about it. + +**Recognition:** The pattern is recognisable in minutes, once the signs are known: + +* Claims that have been answered before, repeated as if never answered. +* The register of solemn concern applied, without exception, in one direction. +* A severe allergic reaction to answering any questions posed. +* A cast that is small, overlapping, and frequently anonymous, with the *plural form* doing the + work of plurality. +* Sockpuppet theater: The same person or footsoldiers thereof appearing as several "supporters" + (and occasionally slipping up mid-performance). +* Articles, ports, and forum threads that cite and reference each other in a closed loop. +* The immediate, reflexive turn to "bullying", "exclusion" and "toxicity" whenever a claim is refuted. +* A complete absence of engagement with the substance of the answers given, and a complete + absence of stake in the network itself. + +**Response:** A constructive response is one that is proportionate, and does not cost the +community its resources, sanity and dignity: + +* Engage the content once, on its merits (if any), with evidence, in public, and then refer to the + existing records. The answers already exist; they do not need to be re-derived for every new + bottle of piss-sour burgundy served from a man behind the curtains. I will do my best to keep this + chapter up to date with such answers and records, for easy reference, but other great resources + exist. +* Do not become part of the theater performance. The "movement" feeds on engagement in *any* form; + attention is its fuel, and outrage is as good as endorsement for them, if not better. +* Do the headcount. When the audience is reminded that a "movement" is a dozen people + recycling answered falsehoods, its projected power dissipates. The power was never real; + only the audience's own assumption of scale can make the illusion effective. A polished-looking + "ground up" implementation might look like the work of many people, but is most likely + just the result of an LLM looping on a laptop for a couple of months (this is weird, but it is + the reality we now live in). Four different users suddenly singing in unison may look like the + representatives of a broader sentiment, but is most likely the same person hiding behind the same keyboard. +* Then, spend the saved time on the networks: On building real infrastructure, putting up nodes + and antennas, on real development, real maintenance, real coexistence, and on the people + *who actually use Reticulum*. The things that we can only do *together*, as humans. That is + what the fake "movement" cannot do, no matter how fluent and smooth its productions become. + +.. _brandolinis-health-and-coexistence: + +Network Health & Coexistence +---------------------------- + +.. _brandolinis-substance: + +Substance Of The Networks +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Before examining health, we should consider what is being protected. The networks are not a repository. They are not a website, a social presence, or a set of marketing pages. They are a habitat: A living commons of communication, carried by, from a catious estimate, an intermesh now consisting of over a hundred thousand physical devices, embedded in a plethora of applications and packages, transporting terabytes of traffic every single day - real messages, real coordination, real people - across radios, serial lines, phones, laptops, and backbone servers, in cities, places and ways that no other network reaches. + +The protocol belongs to humanity; no one owns it. The network belongs to everyone on it, and its membership is defined by nothing other than participation: A node on a mast, a phone in a pocket, a server routing for its neighbourhood, a developer building on the commons. The network has no gatekeepers because it needs none; it is held together by the same physics and mathematics everywhere, and by a shared expectation of how members behave. That expectation - unwritten, unenforced by any central authority, and just as important as any code - is the subject of this section. The *Zen of Reticulum* calls the software a habitat. A habitat is healthy or unhealthy as a whole, and the health of this one is decided, every day, by the people who live in it. + +.. _brandolinis-property-of-the-whole: + +Health Is A Property Of The Whole +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A network is not made healthy by the excellence of any single part. It is made healthy by the behaviour of every part on the shared medium, and how they interact. And the shared medium is the point. When your node transmits, it transmits into the same spectrum, the same line, the same time, the same mathematical address space, the same bandwidth that its neighbours depend on. + +The network cannot be certified by any single project's claims. A node that is a bad neighbour, that invents its own channel behaviour on shared spectrum, that announces without discipline, that spawns tens of thousands of links to scrape the network, that floods and retries without mercy, is a hazard to every node that shares its medium, regardless of how well its "creator" imagines its own code to work in isolation. + +On a shared medium, "my software works" is not a complete sentence. The complete sentence is "my software works *and coexists*". A network's health deteriorates with its worst-behaved member, and every member has a responsibility to not be *that* member. There is no final, technical solution for this; the solutions are human. + +.. _brandolinis-history-of-what-works: + +A History Of What Works +^^^^^^^^^^^^^^^^^^^^^^^ + +Let's recall, because it is the ground truth this entire thing rests on, that the coexistence model has *worked* - is working, right now, **at scale**. Reticulum's protocol decisions have been discussed and evaluated in the community, openly, for years. Protocol upgrades have been designed, coordinated, and executed between a loosely organised group of independent developers, node operators, and users - and have succeeded, repeatedly, without any corporate board, without any central command, and without the collapse that the skeptics predict every second week (while screaming for *GOVERNANCE*). The reference implementation has been developed in the open for over a decade, by a maintainer who answers for it, fixes bugs or issues within hours of their discovery, and is set down in code deliberately kept small enough (the entire protocol implementation under 15,000 lines, including its comments) for a human to read, verify, *and challenge*. + +This is the empirical baseline that every narrative examined in :ref:`A Movement Of A Dozen` conveniently ignores, in order to justify: + +* The claim that the project is a one-man dictatorship +* The claim that the community is excluded +* The claim that the networks need saving from their own founders + +The **reality**, documented and reproducible, is that a loose community of humans coordinates complex technical evolution *without* the apparatus the narratives insist is missing. The health of the networks is not a promise for the future; it is a demonstrated property of the past and present, under the leadership and community model that brought it into existence and navigated it through difficult decisions and situations over a decade. **My job is to keep it that way**, and you can be damned certain that I take it seriously. + +.. _brandolinis-role-of-the-individual: + +The Role Of The Individual +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The networks are built by physical acts and human coordination. You cannot prompt an antenna into existence. No model can string up a dipole, or stand in the rain aligning a radio, or coordinate with a neighbour three valleys away about who covers which repeater frequency, or sit down with a newcomer and explain why their first node didn't announce. These are the acts that make a network *organic* - present in the physical world, resilient because it is *real*, valuable because it is *human*. The machines and technology we use are tools aimed at a well-defined, openly described goal. But the networks themself are composed of intentional human actions, and every node operator is infrastructure for other humans. + +This has a corollary for the individual: You do not need permission, and you do not need to be an expert, to participate. Run a node. Help a neighbour. Ask questions in the community, and answer the questions you can. Build something small at first. The network grows by these acts, and they are the most meaningful ones - the things that can only be done together, as humans, in the physical world. The parasitic "movement" that haunts the peripheries of this ecosystem cannot do any of this. It cannot build a node because it does not exist, in any real connected and human sense; only people can, and people are precisely what a self-recurrent loop lacks. + +.. _brandolinis-place-of-new: + +The Place Of New Implementations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The future of the network includes more implementations - and they are welcome. This chapter is not an argument against implementing Reticulum. The protocol is public domain, by design, and the network is made stronger by genuine diversity: More *good* implementations, honestly made, mean more resilience, more experimentation, more people who understand the protocol deeply *because they have built it themselves*. That is the goal: **For people to understand and own the technology they rely on**. Not to spew out 600,000 line rust ports that fills no meaningful gap or purpose. + +What the ecosystem needs, from every implementation, is the ordinary floor that :ref:`Evaluating A Reticulum Implementation` establishes, and that the reference has met for over a decade: A human who made it and answers for it; provenance disclosed; attribution given; benchmarks honest or absent; interop demonstrated against the real network; code a human can read. And it needs the one thing that costs nothing and changes everything: **Honest labeling**. + +An experimental implementation that says, plainly, as the first thing a user sees: "This is in-progress, experimental, do not depend on it yet, but help if you can", that is a gift to the ecosystem. It contributes, it invites participation, and it protects users. + +The opposite, the polished "drop-in replacement", does damage far beyond its own users: It dissuades the honest developers who might have built *the real thing*, because the polished slop persuades them the work is already done. That dissuasion is one of the quietest and most expensive harms in this entire affair, and the antidote is honesty at every project's door. + +.. _brandolinis-expanding-commons: + +Expanding The Commons +^^^^^^^^^^^^^^^^^^^^^ + +Coexistence, reduced to its essentials, is a short formula; the duties of membership in a network no one owns: + +* **Be honest.** Say what you are, what you built, how you built it, and what you used to + build it. Label experimental work as experimental. Credit the work you build on, including + the reference implementation, in the licenses and in the prose. Concealment is not a + defence; it is a very clear diagnosis marker. +* **Be owned.** Have a human who made the work and can answer for it. Use assistance, don't + substitute. Never sign what you cannot answer for. The chain of accountability is the + community's only verification at scale, and every link in it is a *person*, not a facade. +* **Be a good neighbour.** Respect the shared mediums. Do not invent new behaviour in our + shared space and call it progress. The network belongs to its other members as much as + to you. +* **Verify against the network.** Compatibility is a property demonstrated with actual nodes, + on actual media, against the actual current protocol, over a period of *years*, not 48 hours. + And not a claim pinned to an old snapshot over loopback. +* **Participate as a member.** Ask, answer, help, build. *Advertising at* the community is not + the same as being part of it, and it is **not** the first thing you should do. + +None of this is a high bar. It is the bar the reference implementation has met, in public, for over a decade, and the bar the ecosystem has adopted organically itself, successfully, through every protocol upgrade it has ever coordinated, and everything running on Reticulum today, that people actually use. It is not a new requirement; it is the existing, working culture of the networks, now written down so that newcomers can find it and so that those who would exploit us cannot claim they never saw it. + +.. _brandolinis-defence-of-commons: + +Defence Of The Commons +^^^^^^^^^^^^^^^^^^^^^^ + +The networks need defending - not because they are under severe physical attacks (yet), but because attention, talent and resources is being stolen from them, trust is being mined against them, and its newcomers are being harvested by the machinery documented in this chapter. Defence, for a commons, has specific shapes, and it is not what the theater would like it to be. + +* Defence is **documentation**: Records kept public, of what was claimed, what was + answered, and what turned out true. +* Defence is **a headcount**: Calm, unexcited reminders that a "movement" might just be a dozen + people having a tantrum. +* Defence is **honesty in action**: The visible, ordinary practice of the good behaviour + by the people who actually run the networks. +* And defence is **building**: Every node raised, every page of *real* documentation, every + honest implementation, every new user helped into the community with the knowledge to know + what they are doing is more durable than any rebuttal, because it adds to the thing being + defended. + +---- + +**The theatre cannot keep up with a network.** + +**It can only orbit it, while it recycles its own sour piss.** + +---- + +A lot of us rely on these networks every day. They carry our messages, our coordination, our friendships, and in some places, our safety. That is exactly why they are a target: + +They are valuable, free, and very hard to shut down. The response is not to become aggressive. It is to be *more* of what the network already is: Real, open, owned, and shared. + +*Mark* + +.. _brandolinis-prns: + +Addendum A: The Prns Case +------------------------- + +.. _brandolinis-purpose-and-scope: + +Purpose & Scope +^^^^^^^^^^^^^^^ + +This section provides a concrete example, which future evaluations can use as a template. Its purpose is not to be the last word on this particular subject, but to be an example of how the ideas in this chapter can be applied, and to make the next such examination easier. + +The subject of this case study is **Prns**, a project published at the repository ``github.com/KenAKAFrosty/Prns``, presented as a "ground-up implementation of Reticulum, written in Rust", marketed as faster, safer, and more strictly tested than the reference, widely promoted with the claim of "up to 89× the throughput" of the reference implementation, and an "author" actively engaged in the tactics described in :ref:`A Movement Of A Dozen` on online platforms. The record described below is the project's own, and sourced from its GitHub repository, analyzed locally. + +.. _brandolinis-project-in-brief: + +The Project In Brief +^^^^^^^^^^^^^^^^^^^^ + +* **Time span.** 3,374 commits between 2026-05-26 and 2026-09-12: approximately 110 days, + at a mean rate of ~31 commits per day. Monthly: 132 / 1,137 / 1,097 / 805 / 203. +* **Authorship.** 3,252 of 3,374 commits (96.4%) are authored by a single account. A + second identity, "Prns Tests tests@example.test" - a fictitious identity on a reserved + domain - contributed 35 commits, every one of them website and marketing content. +* **Size.** 3,519 tracked files; 1,983 Rust files; 636,226 lines of Rust; approximately + 22.7 MB of Rust source; 69.5 MB of total repository content. +* **Scope claimed.** A daemon ("drop-in replacement" for the reference daemon), embedded + firmware for three microcontroller families (including six ESP32-S3 board variants and + nRF52840), SDKs and bindings for nine languages, a browser-based node and web flasher, a + twelve-language website, a benchmark apparatus with its own publication and "proof" + pipeline, and a validation hub with oracles, fuzzing, mutation testing, and formal-proof + claims. +* **Marketing claims.** "Ground-up implementation of Reticulum"; "up to 89× the + throughput"; "48× smaller peak-memory footprint"; "33× the energy efficiency"; + "Measured, not just claimed"; "Enforced, then audited"; "byte-for-byte wire parity with + the reference implementation"; "works with Sideband, NomadNet, MeshChat, etc."; + "no_std (no alloc required either)". +* **Status at the time of writing.** Version 0.3.7; published version history begins at + 0.3.0. The repository continues to receive commits. + +.. _brandolinis-prns-question-1: + +Question 1: Is this a clean implementation, or was it directly generated from the reference? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The first of the two deciding questions from :ref:`Evaluating A Reticulum Implementation` is settled by the project's own record. An actual :ref:`clean-room` implementation, reasoned out and written by humans, would owe nothing to any license. The data available shows clearly that Prns is not that. + +* **The founding state.** The first commit, "Scaffold Personal Reticulum suite", contains + the scaffolding of not one but two ports - ``personal-rns`` and ``personal-lxmf``\ , the latter + being the reference's companion messaging protocol - together with a daemon scaffold and + a 233-line founding document, ``docs/build-ethos.md``. That document declares the project's + goal as a "performance-focused drop-in-replacement for rnsd" and its governing principle + as: "Port the contract, not the implementation." It further states directly to the + machine-loop, that **"You owe the reference fidelity at exactly two boundaries: + The wire... The behavior. ... Between those two boundaries, the model is yours"**. + At this point, the very first commit, effectively the whole of the implementation design + and any relevant decisions are handed over to the LLM. +* **Continuous ingestion from the reference.** 506 commits reference RNS or Reticulum + source behaviour; the word "parity" appears in 49 commit messages. Commits cite the reference + implementation's own source locations (for example ``Transport.py:1367``) when correcting + their own divergences and mistakes. +* **Byte-level fidelity as an explicit goal.** Within 48 hours of the first commit, the + record shows a "crypto adapter - vetted primitives, byte-exact vs RNS 1.3.1", and a wire + implementation matching the reference's packet header layout. The project's own + validation apparatus decodes wire vectors using the reference implementation's own + packet parser, and the interop suite consists of real, stock-RNS peer nodes - that is, + the reference source itself, used as the ground truth against which this LLM output is + checked, and committed as accepted and verified after 48 hours of the project's recorded start. +* **The marketing mismatch.** The same record that documents all of the above describes the + project, publicly, as "a ground-up implementation of Reticulum" - while declining, on its + website, to link to the reference implementation at all: the entire tree mentions the + reference's author in six files, and the website in none. + +Conclusion: the project's own history and commit record establishes that it was generated directly from the reference implementation's source code, not reasoned out from the public-domain protocol. It is a derivative of licensed work within the meaning of :ref:`the Reticulum License` and :ref:`general copyright law`. The "ground-up" claim, which carries its entire legal and marketing posture, is disproven by the project's own history. + +.. _brandolinis-prns-question-2: + +Question 2: Who, or what, is the agent of the work? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The second deciding question is answered by the application of :ref:`Assistance Versus Machine Substitution` criteria to the project. + +**Scope that no human could have authored** + +636,226 lines of Rust in 110 days is approximately 5,800 lines per day, every day, including weekends - with 149 commits recorded between midnight and 06:00, and Saturday the single busiest weekday. No human review or decision capacity is commensurable with this volume; the review capacity and the output volume are structurally incommensurable, which is the definition of unauthored scope. + +**Uniform generation** + +The record shows no sign of human development, growth, or learning: No contested decisions, no style drift. Instead: endless renaming (in the first 48 hours: ``State → EngineState → TickInput → TickOutput``\ ), uniform fluent register in every commit, and the exact same, synthetic voice in code, documentation, and website copy. + +**Discovery by regeneration** + +Corrections arrived by the machine's own subsequent runs, recorded as planned milestones. In early July 2026, a series of "core review" commits documented, in the project's own words: + +* announce-ID history "was unbounded per-slot growth" (\ ``54cc8d601``\ ); +* interface announce limiting could "leak a sustained flood" (\ ``9d27af75c``\ ); +* a "phantom-airtime leak" where frames "used to vanish silently" (\ ``4ed75ffdd``\ ); +* Group-packet deduplication "which RNS does not do" - a behaviour the reference never had, + implemented and later removed (\ ``edd8e72be``\ ); +* "both ``unwrap_or(&[])`` arms were unreachable dead defaults" (\ ``74bea355e``\ ); +* a benchmark crate "hasn't compiled since" a prior rename, undetected for weeks because it + was outside the CI's workspace (\ ``86240b027``\ ). + +Earlier still: the record shows a ">1 MiB RNS-to-Prns interop stall" closed three weeks in +(\ ``cc4d524a3``\ ), and a known send-path hang shipped with the note "typed fast-fail a +candidate for later" (\ ``a010e6613``\ ). + +**Laundered provenance** + +The repository contains a committed commit-message hook (\ ``.githooks/commit-msg``\ ) that *blocks* any commit containing attribution for machine generation ("generated with claude/codex/copilot/cursor/gemini", "co-authored-by"), with the explanation "The committer owns the commit". The contributing guide is explicit: "AI tools ... are welcome ... what you submit is *yours*", and describes the contributing population as "both human and automated contributors". The fictitious "Prns Tests" identity completes the picture: A manufactured, unknowable contributor, used for marketing content. + +**Authorship by assignment** + +The human whose name is on the work cannot answer for it, because the choices were never made by a human, and only the general shape and constraints of the outward presentation was. Nothing in the project's history shows an individual explaining a design decision, accepting a mistake in the first person, or going deeper under technical questioning; the record shows process language and marketing instead. Per the earlier mentioned test: any other person could have pressed the same button, and nothing would be different. The project is effectively unowned, and void of value. + +By the criteria of :ref:`Assistance Versus Machine Substitution`, this is substitution. The machine was the agent of the work; the "author" was a facade. + +.. _brandolinis-prns-performance: + +The performance claims +^^^^^^^^^^^^^^^^^^^^^^ + +The project's central marketing claim - "up to 89× the throughput" of the reference - is also its most completely documented failure, because the project published the evidence of its own measurement. The apparatus, the results, and the problems are all on the record. + +**The claim** + +The README states "up to 89× the throughput"; the on-network marketing page repeats "up to 89× the throughput, 48× smaller peak-memory footprint, and 33× the energy efficiency of stock RNS 1.4.2"; the website's front page carries the tagline "Measured, not just claimed". + +**The apparatus** + +The reference is loaded through ``benchmarks/reference/compiled_reference.py``\ , which installs ``pyximport`` and then asserts two things: that ``RNS.compiled == True``\ , and that at least *one* RNS module was loaded from a native extension. The project's own published "proof" records show exactly what those checks captured, on every platform: + +.. code-block:: + + aarch64-apple-darwin: .../RNS.cpython-313-darwin.so, Cython 3.2.8, Python 3.13.13 + x86_64-unknown-linux-gnu: .../RNS.cpython-313-x86_64-linux-gnu.so, gcc 11.4.0 + x86_64-pc-windows-msvc: ~/.prns-oc/lib.win-amd64-cpython-313/RNS.cp313-win_amd64.pyd + +In every case the recorded native module is the **top-level package only** - ``RNS.so``\ , nothing below it. Nothing named ``RNS.Transport``\ , ``RNS.Destination``\ , ``RNS.Packet``\ , ``RNS.Link``\ , or ``RNS.Resource`` ever appears, because *nothing below the top level was ever compiled*. Nobody bothered to check or verify *anything* here. + +The machine output was simply taken for truth, and a full marketing strategy was spun and produced on it. "RNS 1.4.2 (compiled)" - the label used in every table, chart, and marketing page - *is not a mode of RNS that exists*, but the hallucinations of a machine, which the humans created a marketing strategy on. In reality, it is the old ``CRNS`` development shim, whose top-level-only, debug-oriented "compilation" is slower than plain interpreted RNS, and which was *defunct for over a year* before these benchmarks were published. + +**Interface choices** + +The harness writes the reference's configuration itself (\ ``benchmarks/reference/participant_node.py``\ ): ``TCPClientInterface`` for the initiator, ``TCPServerInterface`` for the responder and both relay sides, with ``UDPInterface`` as the abstract wire. The reference was never given its modern ``BackboneInterface`` on any platform, forcing the slowest possible interrfaces. The interface selection is never mentioned in any methodology text. + +**The policy** + +The published default-policy tables record the asymmetry directly: Prns at 500 Mbps / 128 KiB TCP policy against the reference at 10 Mbps / 8 KiB - slyly footnoted as "preserves each implementation's normal TCP policy" (in the case of RNS, a conservative default policy that was selected to prioritize coexistence on slower, shared links, requiring the user to dial it up to full speed if they knew what they were doing). Raw transport "throughput" ratios of 20.65× (Linux) and 38.84× (Windows) are therefore mostly policy, not engine. + +**The cross-host evidence** + +The published results show the same scenario producing wildly different ratios by host, and the variance is entirely in the reference artifact: + +.. list-table:: + :header-rows: 1 + + * - Host + - Prns, single-packet + - "Reference", single-packet + - Ratio + * - macOS (Apple M4) + - 37.4k/s + - 420/s + - 89.09× + * - Linux (i7-1260P) + - 25.3k/s + - 3.5k/s + - 7.19× + * - Windows (Ryzen 5 5600X) + - 30.8k/s + - 3.9k/s + - 8.00× + +Prns is consistent (25–37k/s). The reference artifact collapses to different depths on different hosts, and the single worst collapse - 420 packets per second on macOS - is the cell selected as the global headline. The "89×" is not a measure of Prns; it is a measure of how badly the broken baseline happened to fail on one host. + +For reality calibration: Stock, interpreted RNS 1.5.4 on an ordinary mid-range laptop, single core, sustains roughly 30,000 single-packet deliveries per second (including ephemeral-key decryption), ~175,000–280,000 packets per second in transit relay, and on the order of 10 Gbps at 16 KiB payloads. The project's "compiled" artifact measured 420–3,900 packets per second for its single-packet scenario: An order of magnitude or more *below* stock interpreted RNS. The comparison being marketed was not "Rust vs Python"; **it was "an implementation running under optimal conditions versus a mislabeled, broken shim on a slow legacy interface at a severe policy disadvantage"**. + +**The equalized rows** + +The project's own "1 Gbps policy" rows, in which both sides are explicitly configured identically, publish ratios of roughly 2.4–8.4× across all hosts and scenarios - still against the broken baseline, but nowhere near 89×, and consistent with the ordinary, uncontroversial observation that a native implementation tends to outperform an interpreted one in raw throughput. That point needed no fudging to make, and is banal. + +Interestingly, though, it seems that Prns is really only *marginally* faster than a Python implementation, running in interpreted mode, on a single CPU core. + +**Assessment** + +The front page says "Measured, not just claimed." The record shows the opposite ordering: claimed, and arranged to look measured. No methodology section anywhere states what "compiled" means, that it is a deprecated development shim, that it builds debug targets, or which interface the reference was given; the one statement of the policy asymmetry appears in a footnote of the results tables themselves. If they did not need to fudge it, they would have published the method clearly. + +.. _brandolinis-prns-overall: + +Overall Evaluation +^^^^^^^^^^^^^^^^^^ + +Evaluated against the conditions of :ref:`Evaluating A Reticulum Implementation`: + +* **Provenance and attribution.** Fails: The fake "ground-up" origin story; zero reference links + on the website; a single well-hidden link in the README; a license file reading + ``Copyright (c) 2026 The Prns Authors`` over work directly generated from the licensed reference; + no original copyright or permission notice anywhere. +* **Agency and answerability.** Fails on every criterion of :ref:`Assistance Versus Machine Substitution`: + Unauthored scope, uniform generation, discovery by regeneration, laundered provenance, + authorship by assignment. +* **Engineering.** Fails: The benchmark apparatus above; interop demonstrated only + against a pinned, outdated reference version over loopback while the marketing claims current + parity, interop failures with stock RNS; vendored prebuilt binaries and a republished fork + of an upstream crate (``nrf-softdevice 0.1.0-prns.1``) with no verifiable provenance; + committed WASM bundles. +* **Network behaviour.** Fails: Invented spectrum behaviour and compatibility claims + about third-party applications of the reference ecosystem (Sideband, NomadNet, MeshChat) + that are not established by any evidence. +* **Monetary and influence signals.** The marketing apparatus - website before protocol, + day-three twelve-language marketing, false benchmark headlines, "audited" and "formal proof" + claims - the conformal surface described in :ref:`Evaluating A Reticulum Implementation`: + is where this project invested. + +.. _brandolinis-prns-licensing: + +Licensing Analysis +^^^^^^^^^^^^^^^^^^ + +Applying the two legal layers established in :ref:`Copyright & The Two Legal Layers`: + +**Layer A - copyright infringement (license-independent)** + +The record shows a direct copy roundtrip: the licensed reference implementation fed into a machine, transformed, at a scale and cadence no human could review, with a license file asserting a fresh copyright in the operator's name and no acknowledgment of the work the project was generated from. No substantial, new human creative input is demonstrated anywhere in the record - the founding document explicitly frames the design as an instructed port of the reference's contract. A primarily machine-generated copy of a copyrighted work, not accompanied by demonstrable substantial human creative input, is a derivative work over which the copier holds no copyright, and a reproduction of which without the original author's permission infringes the original author's copyright. This holds under any license, MIT included. The operator's copyright claim over the result is, on this evidence, not merely unsubstantiated; it is the absence of one, directly asserted in the project's own writing. + +**Layer B - license conditions (Reticulum License specific)** + +Modern Reticulum - the current wire format, the AES-256-based link encryption, ratchets, the cryptographic machinery as it exists today - has been published under the Reticulum License since April 15, 2025, effective from release 0.9.4 and every release since. As a derivative of that work, the license's conditions attach: The copyright and permission notice must be included in all copies and substantial portions; the AI-training condition must be honoured; the harm condition must be honoured. The record shows none of the notice requirements met, and a production process that consists of the licensed work being ingested into a machine and regurgitated, at industrial scale and cadence. + +**The cascading consequence** + +Prns is distributed claiming dual MIT/Apache-2.0 licensing. It is, however, a direct derivative of Reticulum-licensed work, and the claimed grant is therefore void. Every downstream project that builds on Prns believing it is MIT/Apache-licensed is building on a grant that does not exist. The users of Prns, and all software developers using it, have in effect, been placed under conditions they were never told about. The "ground-up" claim is not merely false; it is the sole load-bearing element of an entire licensing posture, and it fails spectacularly. + +.. _brandolinis-prns-consequences: + +Consequences +^^^^^^^^^^^^ + +The consequences of this pattern are examined in the following sections: The harm to users and to the network in :ref:`A Movement Of A Dozen`, and the human dimension in :ref:`Network Health & Coexistence`. The contribution of this addendum is narrower and intended as an instructive example: This is what a substitution project looks like, in full, on its own record. It is a reference example for :ref:`Evaluating A Reticulum Implementation`, and it demonstrates, in one case, most of the elements this chapter describes. + +.. _brandolinis-prns-verdict: + +Verdict +^^^^^^^ + +Applying the three verdicts of :ref:`Evaluating A Reticulum Implementation`, this project does not meet the standard. It is not "experimental but honest" - it is not labeled as experimental anywhere; the first thing users saw was a polished marketing presence promising a finished, tested, drop-in replacement. It is a project whose central claims are fabricated (the performance apparatus), whose provenance is laundered (the authorship machinery), whose foundation is misrepresented (the "ground-up" story), whose core semantics were learned late and by regeneration, and whose operator cannot possibly answer for any of it. It is also a blatant copyright violation of the reference implementation. + +The proposed conclusion, for users and for the network: Treat the Prns project as hostile regardless of its polished surface, and as a hazard insofar as it invites users onto shared networks. Nothing in this section is a judgment about the people involved; it is a reading of the results produced, their history and how they came to be, which in the regrettable lack of any human authorship is the only thing that can be expected to be held to account. + +.. _brandolinis-prns-dating: + +Dating +^^^^^^ + +This examination reflects the publicly available material as of September 2026; the repository in question continued to receive commits at the time of writing, so readers should treat citations to commits and files as point-in-time evidence. A `forensics snapshot `_ is publicly available on GitHub. diff --git a/docs/manual/_sources/git.rst.txt b/docs/manual/_sources/git.rst.txt index 6cedd1b0..3699be39 100644 --- a/docs/manual/_sources/git.rst.txt +++ b/docs/manual/_sources/git.rst.txt @@ -8,6 +8,16 @@ This chapter of the manual serves as the technical reference for the distributed A set of utilities for distributed collaborative software development and publishing are included in RNS. +.. only:: html + + .. image:: screenshots/rngit.webp + :align: center + +.. only:: latex + + .. image:: screenshots/rngit.png + :align: center + The system consists of two parts: The ``rngit`` node that hosts repositories, and the ``git-remote-rns`` helper that enables Git to communicate with rngit nodes. As soon as you have RNS installed on your system, you can transparently use Git with Reticulum-hosted repositories just like any other type of remote. Git over Reticulum uses URLs in the following format: ``rns://DESTINATION_HASH/group/repo``. If you set a branch to track a Reticulum remote as the default upstream, you can simply use ``git`` as you normally would; all commands work transparently and as expected. @@ -133,6 +143,9 @@ To create a new empty repository on a remote node: This creates a bare Git repository at the specified path. You must have ``create`` permission for the target group. When a repository is created, the creator automatically receives ``adm`` (admin) permissions on the repository through an auto-generated ``.allowed`` file. +.. tip:: + If you want to use a different primary branch name than ``master``, you can change it inside the bare git repository directory with ``git symbolic-ref HEAD refs/heads/name_of_other_branch``. + **All Command-Line Options (rngit create)** .. code:: text @@ -683,6 +696,7 @@ The following template files are supported: - ``commit.mu`` - Individual commit detail page - ``refs.mu`` - Branches and tags listing - ``stats.mu`` - Statistics page +- ``no_ident.mu`` - Displayed to non-identified initiators if blocked Templates can include the following variables: diff --git a/docs/manual/_sources/index.rst.txt b/docs/manual/_sources/index.rst.txt index d00efa5c..fd305241 100644 --- a/docs/manual/_sources/index.rst.txt +++ b/docs/manual/_sources/index.rst.txt @@ -32,6 +32,7 @@ to participate in the development of Reticulum itself. support examples license + brandolinis .. toctree:: :maxdepth: 2 diff --git a/docs/manual/_sources/software.rst.txt b/docs/manual/_sources/software.rst.txt index c7314aa1..66315fea 100644 --- a/docs/manual/_sources/software.rst.txt +++ b/docs/manual/_sources/software.rst.txt @@ -4,146 +4,225 @@ Programs Using Reticulum ************************ -This chapter provides a non-exhaustive list of notable programs, systems and application-layer -protocols that have been built using Reticulum. +This chapter provides a non-exhaustive list of notable programs, systems and application-layer protocols that have been built using Reticulum. -These programs will let you get a feel for how Reticulum works. Most of them have been designed -to run well even over slow networks based on LoRa or packet radio, but all can also be used over fast -links, such as local WiFi, wired Ethernet, the Internet, or any combination. +Many different applications using Reticulum already exist, serving a wide variety of purposes from day-to-day communication and information sharing to systems administration and tackling advanced networking and communications challenges. -As such, it is easy to get started experimenting, without having to set up any radio -transceivers or infrastructure just to try it out. Launching the programs on separate -devices connected to the same WiFi network is enough to get started, and physical -radio interfaces can then be added later. +.. tip:: + For ease of discovery while reading this manual over the web or as an e-book, links provided in this chapter primarily point to repositories and pages located on internet servers. In many cases, these are public web mirrors, with the upstream repositories residing on Reticulum nodes. For the latest source, updates and information regarding any project, be sure to check their Nomad Network or ``rngit`` nodes. -Programs & Utilities -==================== +These programs will let you get a feel for how Reticulum works. Most of them have been designed to run well even over slow networks based on LoRa or packet radio, but all can also be used over fast links, such as local WiFi, wired Ethernet, the Internet, or any combination. -Many different applications using Reticulum already exist, serving a wide variety of purposes -from day-to-day communication and information sharing to systems administration and tackling -advanced networking and communications challenges. +As such, it is easy to get started experimenting, without having to set up any radio transceivers or infrastructure just to try it out. Launching the programs on separate devices connected to the same WiFi network is enough to get started, and physical radio interfaces can then be added later. -Development of Reticulum-based applications and systems is ongoing, so consider this list -a non-exhaustive starting point of *some* of the options available. With a bit of searching, -primarily over Reticulum itself, you will find many more interesting things. +Development of Reticulum-based applications and systems is ongoing, so consider this list a non-exhaustive starting point of *some* of the options available. With a bit of searching, primarily over Reticulum itself, you will find many more interesting things. -Remote Shell -^^^^^^^^^^^^ +Browsing & Publishing +===================== -The `rnsh `_ program lets you establish fully interactive -remote shell sessions over Reticulum. It also allows you to pipe any program to or from a -remote system, and is similar to how ``ssh`` works. The ``rnsh`` program is very efficient, and -can facilitate fully interactive shell sessions, even over extremely low-bandwidth links, -such as LoRa or packet radio. +In addition to the programs listed in this section, other Nomad Network clients include: -In addition to the default, fully interactive terminal mode, -for extremely limited links, ``rnsh`` offers line-interactive mode, allowing you to interact -with remote systems, even when link throughput is counted in a few hundreds of bits per second. - -.. raw:: latex - - \newpage +- `MeshChatX `_ +- `Columba `_ Nomad Network ^^^^^^^^^^^^^ -The terminal-based program `Nomad Network `_ -provides a complete encrypted communications suite built with Reticulum. It features -encrypted messaging (both direct and delayed-delivery for offline users), file sharing, -and has a built-in text-browser and page server with support for dynamically rendered pages, -user authentication and more. +The terminal-based program `Nomad Network `_ provides a complete encrypted communications suite built with Reticulum. -.. image:: screenshots/nomadnet_3.png - :target: https://github.com/markqvist/nomadnet +.. only:: html -`Nomad Network `_ is a user-facing client -for the messaging and information-sharing protocol LXMF. + .. image:: screenshots/nomadnet_6.webp + :align: center + :target: https://github.com/markqvist/nomadnet + +.. only:: latex + + .. image:: screenshots/nomadnet_6.png + :align: center + :target: https://github.com/markqvist/nomadnet + +It features encrypted LXMF messaging (both direct and delayed-delivery for offline users), file sharing, and has a built-in text-browser and page server with support for dynamically rendered pages, user authentication and more. It also includes an RRC client and a suite of network utilities. + + +Ren Browser +^^^^^^^^^^^ + +`Ren Browser `_ is a modern, standalone browser for Nomad Network using the `Reticulum-Go `_ implementation. The project is actively being developed, and should be considered alpha level software, but much of the functionality is already working. If you want to help expanding the ecosystem, this is an excellent project to take a look at. + +.. only:: html + + .. image:: screenshots/ren_browser.webp + :align: center + :target: https://github.com/fr33n0w/rBrowser + +.. only:: latex + + .. image:: screenshots/ren_browser.png + :align: center + :target: https://github.com/fr33n0w/rBrowser + +Ren Browser is great example of an application aiming for true, seamless interoperability with the existing software ecosystem. It can operate fully standalone using it's own embedded `Go implementation `_ of Reticulum, or seamlessly utilise a shared RNS instance already running on the system. RNS Page Node ^^^^^^^^^^^^^ -`RNS Page Node `_ is a simple way to serve pages and files to any other Nomad Network compatible client. Drop-in replacement for NomadNet nodes that primarily serve pages and files. +`RNS Page Node `_ is a simple way to serve pages and files to any other Nomad Network compatible client. Drop-in replacement for NomadNet nodes that primarily serve pages and files. Retipedia ^^^^^^^^^ -You can host the entirity of Wikipedia (or any ``.zim``) file to other Nomad Network clients using `Retipedia `_. +You can host the entirity of Wikipedia, StackExchange or any other ``.zim`` file, to Nomad Network clients using `Retipedia `_. + +.. only:: html + + .. image:: screenshots/retipedia.webp + :align: center + :target: https://github.com/RFnexus/Retipedia + +.. only:: latex + + .. image:: screenshots/retipedia.png + :align: center + :target: https://github.com/RFnexus/Retipedia + + +Git Over Reticulum +^^^^^^^^^^^^^^^^^^ + +The included :ref:`rngit` system provides a fully distributed solution for managing, hosting, collaborating on and interacting with Git repositories over Reticulum. + +.. only:: html + + .. image:: screenshots/rngit.webp + :align: center + +.. only:: latex + + .. image:: screenshots/rngit.png + :align: center .. raw:: latex \newpage +Messaging & Voice +================= + Sideband ^^^^^^^^ -If you would rather use an LXMF client with a graphical user interface, you can take -a look at `Sideband `_, which is available for Android, -Linux, macOS and Windows. Sideband is an advanced LXMF and LXST client, and a multi-purpose Reticulum -utility, with features and functionality targeted at advanced users. +`Sideband `_ is a technical LXMF and LXST client, for Android, Linux, macOS and Windows. It also serves as a multi-purpose Reticulum utility, with features and functionality targeted at advanced users. .. only:: html .. image:: screenshots/sideband_devices.webp :align: center - :target: https://unsigned.io/sideband + :target: https://github.com/markqvist/Sideband .. only:: latex .. image:: screenshots/sideband_devices.png :align: center - :target: https://unsigned.io/sideband + :target: https://github.com/markqvist/Sideband -Sideband allows you to communicate with other people or LXMF-compatible -systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, Encrypted QR -Paper Messages, or anything else Reticulum supports. +Sideband allows you to communicate with other people or LXMF-compatible systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, Encrypted QR Paper Messages, or anything else Reticulum supports. -It also interoperates with all other LXMF clients, and provides advanced features such as voice messaging, -real-time voice calls, file attachments, private telemetry sharing, and a full -plugin system for expandability. +It interoperates with all other LXMF clients, and provides advanced features such as PTT and voice messaging, real-time voice calls, file attachments, private telemetry sharing, and a full plugin system for expandability. .. raw:: latex \newpage MeshChatX -^^^^^^^^ +^^^^^^^^^ -A `Reticulum MeshChat fork from the future `_, with the goal of providing everything you need for Reticulum, LXMF, and LXST in one beautiful and feature-rich application. This project is separate from the original `Reticulum MeshChat `_ project, and is not affiliated with the original project, but is a much more up-to-date, comprehensive and well-maintained fork. +`MeshChatX `_ is an all-in-one Reticulum client with messaging, calling, and a NomadNet browser, providing everything you need for Reticulum, LXMF, and LXST in one beautiful and feature-rich application. .. only:: html .. image:: screenshots/meshchatx.webp :align: center - :target: https://git.quad4.io/RNS-Things/MeshChatX + :target: https://meshchatx.com/ .. only:: latex .. image:: screenshots/meshchatx.png :align: center - :target: https://git.quad4.io/RNS-Things/MeshChatX + :target: https://meshchatx.com/ -Features include full LXST support, custom voicemail, phonebook, contact sharing, and ringtone support, multi-identity handling, modern UI/UX, offline documentation, expanded tools, page archiving, integrated maps, telemetry and improved application security. +Features include full LXST support, custom voicemail, phonebook, contact sharing, ringtone support, multi-identity handling, modern UI/UX, offline documentation, expanded tools, page archiving, integrated maps, telemetry and improved application security. -.. raw:: latex +Columba +^^^^^^^ - \newpage +`Columba `_ is a simple and familiar LXMF messaging app Android, built with a native Android interface and Material Design 3. It also includes LXST voice call functionality, and a mobile Nomad Network page browser. + +.. only:: html + + .. image:: screenshots/columba.webp + :align: center + :target: https://github.com/torlando-tech/columba/ + +.. only:: latex + + .. image:: screenshots/columba.png + :align: center + :target: https://github.com/torlando-tech/columba/ + + +Ren TUI +^^^^^^^ + +`Ren TUI `_ is an early prototype terminal LXMF client for Reticulum built with Odin on librns (Reticulum-Go). It aims for NomadNet-like messaging/browsing without urwid or ncurses. + +.. only:: html + + .. image:: screenshots/rentui.webp + :align: center + :target: https://github.com/Quad4-Software/Ren-TUI + +.. only:: latex + + .. image:: screenshots/rentui.png + :align: center + :target: https://github.com/Quad4-Software/Ren-TUI + +Chat +==== Reticulum Relay Chat ^^^^^^^^^^^^^^^^^^^^ `Reticulum Relay Chat `_ is a live chat system built on top of the Reticulum Network Stack. It exists to let people talk to each other in real time over Reticulum without dragging in message databases, synchronization engines, or architectural commitments they did not ask for. -The `rrcd `_ program provides a functional, reference RRC hub-server daemon implementation. RRC user clients include `rrc-gui `_ and `rrc-web `_. +.. only:: html + + .. image:: screenshots/rrc.webp + :align: center + +.. only:: latex + + .. image:: screenshots/rrc.png + :align: center RRC is closer in spirit to IRC than to modern “everything platforms.” You connect, you join a room, you talk, and then you leave. If you were present, you saw the conversation. If you were not, the conversation did not wait for you. This is not an accident. This is the entire design. +The `rrcd `_ program provides a functional, reference RRC hub-server daemon implementation. RRC user clients include: + +- `Nomad Network `_ +- `MeshChatX `_ +- `Eridanus `_ +- `rrc-gui `_ +- `rrc-web `_ + RetiBBS ^^^^^^^ -`RetiBBS `_ is a bulletin board system implementation for Reticulum networks. +`RetiBBS `_ is an old-school bulletin board system implementation for Reticulum networks. .. only:: html @@ -163,29 +242,14 @@ RetiBBS allows users to communicate through message boards in a secure manner. \newpage -RBrowser -^^^^^^^^ +Voice & Telephony +================= -The `rBrowser `_ program is a cross-platform, standalone, web-based browser for exploring NomadNetwork Nodes over Reticulum Network. It automatically discovers NomadNet nodes through network announces and provides a user-friendly interface for browsing distributed content with Micron markup support. +In addition to the programs listed in this section, other LXST voice clients include: -.. only:: html - - .. image:: screenshots/rbrowser.webp - :align: center - :target: https://github.com/fr33n0w/rBrowser - -.. only:: latex - - .. image:: screenshots/rbrowser.png - :align: center - :target: https://github.com/fr33n0w/rBrowser - -Includes useful features like automatic listening for announce, adding nodes to favorites, browsing and rendering any kind of NomadNet links, downloading files from remote nodes, a unique local NomadNet Search Engine and more. - - -.. raw:: latex - - \newpage +- `Sideband `_ +- `MeshChatX `_ +- `Columba `_ Reticulum Network Telephone ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,14 +270,31 @@ The ``rnphone`` program, included as part of the `LXST `_ is a group voice application for Reticulum, built on `LXST `_, inspired by `Mumble `_. + +.. only:: html + + .. image:: screenshots/partyline.webp + :align: center + :target: https://github.com/markqvist/LXST + +.. only:: latex + + .. image:: screenshots/partyline.png + :align: center + :target: https://github.com/markqvist/LXST + +It provides both realtime group voice over any Reticulum transport capable of >6 kilobits per second, LXST dial-in support, listen-only music/broadcasting rooms, and many other useful functions. + LXST Phone ^^^^^^^^^^ -The `LXST Phone `_ program is a cross-platform desktop application for performing LXST voice calls over Reticulum. +The `LXST Phone `_ program is a cross-platform desktop application for performing LXST voice calls over Reticulum. It supports various advanced features such as SAS verification, peer blocking, rate limiting, encrypted call history storage and contact management. .. only:: html @@ -227,28 +308,60 @@ The `LXST Phone `_ program is a cross-plat :align: center :target: https://github.com/kc1awv/lxst_phone -It supports various advanced features such as SAS verification, peer blocking, rate limiting, encrypted call history storage and contact management. - .. raw:: latex \newpage -LXMFy -^^^^^ +System Administration +===================== -`LXMFy `_ is a comprehensive and advanced bot creation framework for LXMF, that allows building any kind of automation or bot system running over LXMF and Reticulum. `Bot implementations exist `_ for Home Assistant control, LLM integrations, and various other purposes. +Remote Shell +^^^^^^^^^^^^ +The included :ref:`rnsh` program lets you establish fully interactive +remote shell sessions over Reticulum. It also allows you to pipe any program to or from a +remote system, and is similar to how ``ssh`` works. The ``rnsh`` program is very efficient, and +can facilitate fully interactive shell sessions, even over extremely low-bandwidth links, +such as LoRa or packet radio. -LXMF Interactive Client -^^^^^^^^^^^^^^^^^^^^^^^ - -`LXMF Interactive Client `_ is a feature-rich, terminal-based LXMF messaging client with many advanced features and an extensible plugin architecture. +In addition to the default, fully interactive terminal mode, for extremely limited links, +``rnsh`` offers line-interactive mode, allowing you to interact with remote systems, even +when link throughput is counted in a few hundreds of bits per second. RNS FileSync ^^^^^^^^^^^^ -The `RNS FileSync `_ program enables automatic file synchronization between devices without requiring central servers, internet connectivity, or cloud services. It works over any network medium supported by Reticulum, including radio, LoRa, WiFi, or the internet, making it ideal for off-grid, privacy-focused, and resilient file sharing. +The `RNS FileSync `_ program enables automatic file synchronization between devices without requiring central servers, internet connectivity, or cloud services. It works over any network medium supported by Reticulum, including radio, LoRa, WiFi, or the internet, making it ideal for off-grid, privacy-focused, and resilient file sharing. + +.. raw:: latex + + \newpage + +Utilities & Components +====================== + +Modem73 +^^^^^^^ + +`MODEM73 `_ and its companion `Modem73Interface `_ is an open source software modem that works with any HF, VHF, or UHF radio capable of 2400 Hz of bandwidth. All you need is a sound card and audio cable for your radio. + +.. only:: html + + .. image:: screenshots/modem73.webp + :align: center + :target: https://github.com/RFnexus/modem73 + +.. only:: latex + + .. image:: screenshots/modem73.jpg + :align: center + :target: https://github.com/RFnexus/modem73 + +LXMFy +^^^^^ + +`LXMFy `_ is a comprehensive and advanced bot creation framework for LXMF, that allows building any kind of automation or bot system running over LXMF and Reticulum. `Bot implementations exist `_ for Home Assistant control, LLM integrations, and various other purposes. Micron Parser JS @@ -256,6 +369,25 @@ Micron Parser JS `Micron Parser JS `_ is the JavaScript-based parser for the Micron markup language, that most web-based Nomad Network browsers use. If you want to make utilities or tools that display Micron pages, this library is essential. +Reticulated +^^^^^^^^^^^ + +`Reticulated `_ is a Reticulum Network simulator that spawns live, interactive Reticulum instances controllable from a node-based Web UI. + +.. only:: html + + .. image:: screenshots/reticulated.webp + :align: center + :target: https://github.com/RFnexus/Reticulated + +.. only:: latex + + .. image:: screenshots/reticulated.jpg + :align: center + :target: https://github.com/RFnexus/Reticulated + +You can create networks of any topology and set bitrate, MTU, and configure path loss and propagation behavior. It provides a top-down view to a live network. You can connect any Reticulum application to the simulated network. It also has built in utilities like a basic LXMF chat function and Resource transfer included. + RNMon ^^^^^ @@ -267,6 +399,16 @@ RNMon \newpage +Device Flashers +=============== + +In addition to the included command-line ``rnodeconf`` flasher, several community-provided RNode device flashers exist: + +- `RNS Moscow `_ +- `Aetherlab `_ + +Several programs, such as `Sideband `_ and `MeshChatX `_ also include built-in device flashers that can be used fully offline. + Protocols ========= @@ -298,8 +440,8 @@ Interface Modules & Connectivity Resources This section provides a list of various community-provided interface modules, guides and resources for creating Reticulum networks over special or challenging mediums. -* Custom interface module for running `RNS over HTTP `_ +* `Modem73 `_ is an efficient software modem that can be used with Reticulum +* Custom interface module for running `RNS over HTTP `_ * Guide for running `Reticulum over ICMP `_ using ``PipeInterface`` * Guide for running `Reticulum over DNS `_ with Iodine -* Guide for running `Reticulum over HF radio `_ -* `Modem73 `_ is a KISS TNC OFDM modem frontend that can be used with Reticulum \ No newline at end of file +* Guide for running `Reticulum over HF radio `_ \ No newline at end of file diff --git a/docs/manual/_sources/support.rst.txt b/docs/manual/_sources/support.rst.txt index 39bcf8f3..011f1231 100644 --- a/docs/manual/_sources/support.rst.txt +++ b/docs/manual/_sources/support.rst.txt @@ -28,9 +28,6 @@ Donations are gratefully accepted via the following channels: Ko-Fi: https://ko-fi.com/markqvist -Are certain features in the development roadmap are important to you or your -organisation? Make them a reality quickly by sponsoring their implementation. - .. raw:: latex \newpage diff --git a/docs/manual/_sources/using.rst.txt b/docs/manual/_sources/using.rst.txt index a61c2b30..c31ce7dd 100644 --- a/docs/manual/_sources/using.rst.txt +++ b/docs/manual/_sources/using.rst.txt @@ -274,8 +274,7 @@ You can easily add ``rnsd`` as an always-on service by :ref:`configuring a servi The rnstatus Utility ==================== -Using the ``rnstatus`` utility, you can view the status of configured Reticulum -interfaces, similar to the ``ifconfig`` program. +Using the ``rnstatus`` utility, you can view the status of and control configured Reticulum interfaces, similar to the ``ifconfig`` program. **Usage Examples** @@ -350,6 +349,9 @@ Filter output to only show some interfaces: -h, --help show this help message and exit --config CONFIG path to alternative Reticulum config directory --version show program's version number and exit + --attach name Attach interface by name + --detach name Detach interface by name + --reload name Reload interface by name -a, --all show all interfaces -A, --announce-stats show announce stats -P, --pr-stats show path request stats @@ -367,6 +369,8 @@ Filter output to only show some interfaces: -w seconds timeout before giving up on remote queries -d, --discovered list discovered interfaces -D show details and config entries for discovered interfaces + --show-stale show stale discovery entries + --show-unknown show discovery entries without version info -m, --monitor continuously monitor status -I, --monitor-interval seconds refresh interval for monitor mode (default: 1) @@ -705,7 +709,7 @@ The rnx Utility The ``rnx`` utility is a basic remote command execution program. It allows you to execute commands on remote systems over Reticulum, and to view returned command output. For a fully interactive remote shell solution, be sure to also take a look -at the `rnsh `_ program. +at the :ref:`rnsh` program. **Usage Examples** @@ -771,6 +775,8 @@ another one, which will be created if it does not already exist --version show program's version number and exit +.. _using-rnsh: + The rnsh Utility ================ @@ -1230,6 +1236,8 @@ For more fine-grained control over how discovered interfaces are auto-connected, * The ``autoconnect_announces_to_internal`` option allows you to specify that auto-connected interfaces should propagate announces to ``internal`` mode interfaces, even if the auto-connected interface's mode would normally not allow for this. +* The ``autoconnect_unverified_implementations`` option will allow the interface discovery system to auto-connect to *any* announced interface, even those coming from unverified, experimental or potentially broken implementations. Be very careful with this option. + Remote Management ----------------- diff --git a/docs/manual/_static/documentation_options.js b/docs/manual/_static/documentation_options.js index 5426053b..1e03c972 100644 --- a/docs/manual/_static/documentation_options.js +++ b/docs/manual/_static/documentation_options.js @@ -1,5 +1,5 @@ const DOCUMENTATION_OPTIONS = { - VERSION: '1.5.1', + VERSION: '1.5.5', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/docs/manual/brandolinis.html b/docs/manual/brandolinis.html new file mode 100644 index 00000000..319841f9 --- /dev/null +++ b/docs/manual/brandolinis.html @@ -0,0 +1,1611 @@ + + + + + + + + + + Brandolini’s Reference - Reticulum Network Stack 1.5.5 documentation + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+
+ +
+ +
+
+
+

Brandolini’s Reference

+
+
+
A little learning is a dang’rous thing;
+
Drink deep, or taste not the Pierian spring.
+
There shallow draughts intoxicate the brain,
+
And drinking largely sobers us again.
+

+
- Alexander Pope, 1711
+
+
+

This chapter serves as a helpful reference for developers, users and community members living in an Age of Bullshit Manufacture equivalent to the Cambrian Explosion.

+

As we are surely only at the on-ramp of this trajectory, the chapter will continue to evolve, expand and be updated based on community feedback as events occur.

+
+

What The Reticulum License Is

+

To understand the legal reality relating to this section, see Void Grants.

+

The Reticulum License is the license under which RNS, the Reticulum reference implementation, has been published since April 15, 2025, in versioning effective from 0.9.4 and every release since. In practical terms, it covers all of “modern Reticulum”: The current wire format, the cryptographic machinery as it exists today (including the AES-256-based link encryption, ratchets, et cetera), and all protocol additions that distinguish the modern implementation from the earliest pre-1.0.0 beta formats. If an implementation speaks today’s Reticulum protocol, it is, in all relevant respects, built on Reticulum-licensed work.

+

The license is a permissive license. It grants the full range of rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, free of charge; subject to three conditions, which are reproduced here verbatim:

+
+
    +
  • The Software shall not be used in any kind of system which includes amongst its +functions the ability to purposefully do harm to human beings.

  • +
  • The Software shall not be used, directly or indirectly, in the creation of an artificial +intelligence, machine learning or language model training dataset, including but not +limited to any use that contributes to the training or development of such a model or +algorithm.

  • +
  • The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software.

  • +
+
+
+

Why This License Exists

+

Reticulum was not moved to a custom license casually or quickly. It was licensed under the MIT license for the greater part of its existence, and that served well for a long time. The change came when it became clear that no existing license expressed what the project needed, and that the two most commonly proposed alternatives would either say the wrong thing or say nothing useful at all. Three factors had primary influence on the situation:

+

The harm problem

+

Reticulum is a tool that was built, deliberately and at great cost, to empower people; to make communication something you own rather than something you are temporarily granted. It has also been, at various times, exactly what certain kinds of organisations would like to use to control people. This is the duality of any powerful tool. A permissive license could not, and cannot, say anything about that; MIT is silent on the question of whether the software may be used to build systems designed to harm human beings. The Reticulum License is not silent. It does not pretend that a license can stop an individual madman; it does assert, however, plainly and in enforceable terms, that corporations and organisations integrated into the legal system cannot consume this software for harm and then claim they never knew. The line is drawn by the creators of the tool, not by an external authority, and it is drawn deliberately. This is covered in more depth in the discussion of the ethics of the tool in the Zen of Reticulum.

+

The appropriation problem

+

The second factor was the machine-learning appropriation of the open-source commons. By 2025 that was no longer hypothetical: The commons was already being systematically ingested by corporate training pipelines, and the code, words, and creativity of the people who built it were being converted into synthetic systems designed to replace them. The license responds to this with an explicit condition: The software shall not be used in the creation of an AI, machine-learning, or language-model training dataset, nor in any use that contributes to the training or development of such a model or algorithm.

+

It is important to understand what this condition does and does not do, which matters for what follows in this chapter. The AI-training condition is not the legal basis for protecting the code from machine copying. That protection already exists, in the oldest and most well-tested form of copyright law, and it applies regardless of any license (see Copyright & The Two Legal Layers).

+

The AI-training condition addresses something additional: the appropriation of the code into the models themselves; the ingestion of human-made work as raw material for a synthetic replacement, and the use of that ingestion to fabricate “prior work” minefields, patent-troll material, and a wall of slop meant to bury and devalue the actual ecosystem. That danger was foreseeable; the licensing decision was made with full awareness of it. The events of 2026 have since demonstrated, in public and in detail, that the concern was not theoretical.

+

The sustainability problem

+

Reticulum has been developed and maintained for over a decade by a single person, supported by a small group of contributors and network-building users, without corporate backing, without VC funding, through several serious attempts at commercialization and takeover from both the corporate and the ideological side. The license is part of what makes that sustainable, and possible at all.

+

It ensures that the specific, painstaking labor of the reference implementation cannot be hijacked to undermine the intent of the project, while leaving the protocol itself, the mathematical rules of how Reticulum works, dedicated to the public domain, where it belongs to humanity and can never be owned. Anyone can implement the protocol, provided they themselves invest the actual work and effort. What the license protects is the work, and the intent embodied in it.

+
+
+

On Freedom

+

The most persistent mischaracterisation of the Reticulum License is that it is “more restrictive” than the licenses it replaced or than the GPL family. This is backwards, and I’ll state the comparison plainly, because the confusion is the foundation of a great deal of deliberately manufactured controversy examined later in this chapter.

+

The GPL and AGPL are constructed around a single, self-referential axiom: that “free” is defined by the terms of the license itself, and that any use falling outside those terms is not free. In practice, this means the GPL restricts the freedom of everyone - you may not write, distribute, link, or (in some cases) even communicate with GPL-covered software without the entire arrangement being pulled under the same terms, which the licensor then controls. The restriction applies to 100% of users, including the ones building purely constructive things.

+

The Reticulum License restricts the freedom of almost nobody. Its restrictions apply only to:

+
    +
  • Those who wish to use the software in systems that purposefully harm human beings, and

  • +
  • Those who wish to ingest the software into AI training pipelines.

  • +
+

That is a restriction on a vanishingly small fraction of would-be users - the 0.0000001% - and it is a restriction they can characterise however they like, forever. The bickering is itself a signal that the licensing decision hit exactly the right target.

+

Everyone else retains the full breadth of use, modification, distribution, and sale, with none of the viral encumbrance of copyleft.

+

Both licenses contain moral axioms. The difference is that the Reticulum License states its axioms out loud:

+
    +
  • Intentionally restricting the way that millions of people use and build upon a foundational +communications technology - The mechanism of copyleft

  • +
  • Intentionally restricting a small number of organisations from using the technology to +violently harm human beings - The mechanism of the Reticulum License

  • +
+

Which of these is more free? The answer is not a matter of committee approval. It is a matter of what the word “free” means to the people whose freedom is at stake. The question of whether “open source” requires the blessing of a particular licensing orthodoxy is examined in Open Source Means Open Source.

+
+
+

The Prediction, And What Happened

+

When the license change was made and publicly discussed in 2025, the following was said, in public, about the machine-learning threat:

+
+

A generative system could be trained on the Reticulum codebase, and for extremely low cost +be set to work spewing out millions of source repositories for all kinds of ridiculous +“Reticulum-based programs”. This is already happening. You can find several examples of this +on GitHub already. … the point of this kind of trolling is to establish as wide a base for +“prior work” as possible. By doing that, a patent troll or IP abuser can create an immense +minefield for real developers.

+
+

This was written when the phenomenon was just beginning. It was not a guess; it was a description of a mechanism already in motion, in the specific context of Reticulum, by people who had already begun to appear around the project.

+

Less than a year and a half later, the prediction has now been demonstrated, in public, exhaustively and to the letter. There are now roughly a dozen machine-generated “Reticulum implementations” of the same shape: fluent, marketing-heavy, some without attribution, and - in several cases - actively harmful to the network. The Prns case is an example documented in this chapter. The pattern that produced it (and the people, mechanisms, and the recycling of falsehoods behind the wider phenomenon) is examined in A Movement Of A Dozen.

+

The license was written, in part, so that when this happened, the community would not be defenceless.

+
+
+

What This Means For Other Implementations

+

Two simple things must be kept separate:

+
    +
  1. The protocol is public domain. The mathematical rules of Reticulum - addresses, +signatures, routing, the wire format as an idea - belong to humanity. A genuine clean-room +implementation of the protocol, written by human beings who reasoned it out themselves, is +free and welcome, and owes nothing to the Reticulum License. Nothing in this chapter is an +argument against implementing the protocol. On the contrary: More good implementations, +honestly made, are good for the network.

  2. +
  3. The implementation is licensed. Copying the reference implementation - by machine or +by silk-screen press - and modifying and redistributing the result, is +exercising rights granted by the license, and is therefore subject to its conditions: The attribution +notice, the harm condition, the AI-training condition. A copy that does not follow those +conditions is not licensed, and it is not “open source in spirit”; it is an unauthorized +derivative work, and therefore a copyright violation.

  4. +
+

The distinction is the same one the license itself makes, and it must be held firmly: An implementation that speaks Reticulum is exercising the public domain protocol, if it was truly created independently. An implementation that was generated from RNS, reproduced by a copy process, is a derivative of licensed work.

+
+ +
+

The “Clean-Room” Delusion

+

I regularly receive mail or LXMF messages from people who proudly and happily proclaim that they have created a “clean-room” implementation of one of the software systems I maintain; RNS, Sideband, LXMF or others. The declaration is delivered with the flat certainty of someone who believes they have found the legal lock-pick that settles everything at once: Their production is independent, uncontaminated, and therefore free of any obligation to the work they copied, its license, or its author. The proclamation usually concludes with a request for blessing, or at least acknowledgment. The proclamation is, usually, also generated by an LLM.

+

This is a delusion, and I’ll cut through it surgically. The word they here invoke as magic is attempting to do a great deal of work it was never able to bear.

+

What a clean room actually was

+

The legal “clean room” is not folklore, incantation, witchcraft or a claim a person gets to make about their own output. It is a very specific, institutionalized procedure that grew out of the hardware and software litigations of the 1980s, and it existed for exactly one purpose: Convincingly proving the absence of copying in a court of law.

+

The canonical case was Phoenix Technologies and its 1984 reimplementation of the IBM PC BIOS. IBM’s BIOS was copyrighted, which meant that the entire PC-compatible industry depended on being able to show that a compatible BIOS had been written independently, and not from IBM’s code. Phoenix’s answer was a physical and procedural firewall:

+
    +
  • One team, the “dirty room”, read the original code and produced written functional specifications: descriptions of what the BIOS did, not how IBM’s code did it.

  • +
  • A second team, the “clean room”, consisted of engineers who had never seen the original code at all, and they wrote the new BIOS from those specifications alone.

  • +
+

This obsessively documented, legally attested separation was not a preference or a willy-nilly show for a kindergarten; it was the entire legal point, and it had to be solid. If even one clean-room engineer had glanced at IBM’s code, the clone would have been contaminated, and the defense would shatter.

+

The other landmark case was Computer Associates v. Altai (1992), in which Altai had copied CA’s scheduler code into its own product, and (upon being caught) hired outside counsel to run a genuine clean-room procedure: A programmer with no exposure to the original was brought in to rewrite the infringing modules from functional specifications prepared by the team that had seen the code. The court credited the good-faith effort precisely because it was done, as the carefully documented record showed, to the letter of the procedure.

+

Bear in mind what this procedure entailed in practice, because this is the part the modern claimants never seem to have even heard of: Physical separation of teams, legal counsel managing the process, signed and notarised declarations of non-exposure, controlled specification documents that described behaviour and never code, months of work, and testing against the specification - not against the original, which the implementers were forbidden to consult.

+

The people on the clean-room side of the wall did not just claim they had not read the code. Their non-exposure was institutionally guaranteed, obsessively documented, and legally attestable through every fart and sneeze of the process, because the entire point was that a court - hostile, adversarial, and entitled to discovery - would believe it.

+

That is the process. “Clean-room implementation” is the name of a certified procedure for proving independent authorship. It is not a mood, a marketing label, or a property a person gets to declare about their own work.

+

The moronic inversion

+

Now consider what is actually being described when someone says: “I created a clean-room implementation of Reticulum by feeding the source code into a machine.”

+

That sentence is the opposite of a clean room. Feeding a copyrighted work into a machine so that it reproduces and transforms the work is the definition of copying, and a clean room is the one procedure whose entire purpose is the demonstrated absence of copying. This process cannot demonstrate the absence of copying, because the process is composed of copying. The cleanest possible room has been replaced by the dirtiest possible room, and the dirt has been installed as the base feature. What these claimants have actually performed is a photocopy with extra steps, and the extra steps, far from cleaning anything, are simply steps that forge a certificate they believe the output has earned.

+

Why the word is deployed

+

The word “clean-room” is deployed because it sounds like what the speaker wishes were true. It carries the accumulated legal prestige of the 1980s and 1990s - the BIOS clones, the Altai credit - and it sounds like a certificate already issued: Independent, original, unencumbered, the work of a person who owes nothing. The claimants want that halo without the procedure: No law firm, no physical separation, no written specifications, no signed declarations, no months of process - just a laptop, a loop, and the word “clean-room” typed into a README. The word must do the work of the process it replaces, and the delusional replacement is the entire point.

+

The irony runs deep

+

The Reticulum protocol is public domain. Any human being can implement it - from the mathematics, from the documentation, from their own reasoning - and owe nothing whatsoever to the license, to the reference implementation, or to me.

+

An honestly written implementation needs no incantations, no legal theater, and no special vocabulary; it simply is what it claims. It’s plain for everyone to see. It’s also plain for everyone to see when you’re faking it. The people who reach for the word “clean-room” are, without exception, the people who need it to create a fantasy - and the people who need that are precisely the people who cannot have it. If what you wrote were genuinely independent work on the public-domain protocol, you would not need to call it anything. The word is not a seal of independence. In this context it is a confession of copying, filed by the copier, in the confident belief that it says the opposite.

+
+
+
+

Open Source Means Open Source

+

An objection regarding the “open source status” of RNS appears occasionally in variations, but always reduces to the same syllogism:

+
    +
  1. “Open source” means licensed under one of the licenses approved by the Open Source +Initiative (or, in other variants, compatible with GPL orthodoxy).

  2. +
  3. The Reticulum License is not on that list.

  4. +
  5. Therefore Reticulum is not open source, and anything built on it is illegitimate.

  6. +
+

The entire argument rests on the first premise, and the first premise is false.

+

Open source is not a certification conferred by a committee. It is a description of a fact: The source code is available, and the rights to use, copy, modify, merge, publish, distribute, sublicense, and sell it are granted to everyone, free of charge.

+

The Reticulum License does all of those things. It is, in every substantive respect that concerns the person who wants to use, study, modify, or build upon the software, an open license. What it adds - and what disqualifies it in the eyes of the orthodoxy - is two conditions on who may do what with the original work, not on what the user is allowed to do with it.

+

The definition being wielded against Reticulum is not even a young one. It is, in essence, the Debian Free Software Guidelines written in 1997, adopted by the OSI in 1998, and treated ever since by certain people as if it had descended from a mountain on tablets. It is an approach that is close to three decades old. Being old is not itself a flaw - but being old is also not a proof of correctness, and the suggestion that the meaning of a word like “open” was settled for all time by a committee in the 1990s, and may never be revisited, is not a position rooted in reason. It is rooted in institutional inertia dressed as principle, maintained by those whose ideologies it serves.

+
+

What The Argument Is Actually Doing

+

I would like to go into some detail about the rhetorical mechanism, because it is roughly the same mechanism that powers the rest of the campaign described later in this chapter.

+

The orthodoxy’s argument is self-referential: “open source means what we say it means, because we are the ones who define it.” When the Reticulum License is measured against that definition and found wanting, the conclusion is presented as a property of Reticulum - when in fact it is a property of the definition. The definition is treated as neutral and authoritative - as some base fact of raw cosmology - and the license is treated as deviant. But the definition is no more neutral than the license is. It encodes a moral position, and that moral position is exactly the one that this project declines to take.

+

Consider what the orthodoxy’s definition requires, in the case at hand. The OSI-based definition contains, in its ancestry, the Debian Free Software Guideline of “No discrimination against fields of endeavor”: The software must not restrict who may use it or for what purpose. Taken to its logical end, this means that open source, properly “certified”, must be equally available to those who build hospitals and those who build weapons, those who connect people and those who control them, those who create and those who ingest and replace.

+

The orthodoxy presents this as neutrality. It is not neutrality; it is a moral position - one that says, in effect, that harming human beings is a field of endeavor like any other, and software must not discriminate against it.

+

The Reticulum License takes a different position, and it has the honesty to state it in the license text: this software is for life, not for death; it is for people, not for the systems that would replace them. That is not a restriction on openness, nor on freedom. It is a restriction on who may consume the work, and it is a restriction the orthodoxy’s definition cannot express - which is why the orthodoxy must always attack the license as “not open source” rather than engage with what it actually does.

+
+
+

Who Is Restricted By Which License?

+

The arithmetic is simple, so let’s do it out loud, because the orthodoxy’s framing inverts it every time.

+

The GPL family imposes its conditions on everyone: You may not distribute, link, or - in the AGPL case - even communicate with GPL-covered software without your own work being pulled under the same terms. “Free” in this system is defined (self-referentially) by the license’s own terms; everything outside those terms is, by definition, unfree. The restriction applies to 100% of users. It applies to the hospital, the mesh community, the school, and the hobbyist with the same force it applies to anyone else. That is not freedom for everyone; it is a specific moral architecture applied to everyone, presented as if it were the absence of one.

+

The Reticulum License imposes its conditions on a fraction of would-be users so small as to be practically unmeasurable:

+
    +
  • Those whose intended use is to build systems that purposefully harm human beings, and

  • +
  • Those whose intended use is to ingest the work into AI training pipelines.

  • +
+

That is the entire list. Everyone else - the overwhelming majority, the community, the developers, the users, the downstream projects - receives the full, unrestricted rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, with none of the viral encumbrance of copyleft.

+

So when the claim is made that the Reticulum License “is more restrictive” than the GPL, the claim is not merely wrong; it is the exact inverse of the truth. The GPL restricts the freedom of everyone, in the name of a specific ideology.

+

The Reticulum License restricts the freedom of the harm-doer and the appropriator, and leaves everyone else free. The two approaches do not differ in whether they contain moral axioms - all licenses do. They differ in whether the axioms are stated openly, and in whose freedom they restrict.

+
+
+

The Consequences Of The “Not Open Source” Claim

+

This would be a footnote debate if the mischaracterisation had no practical consequences. It has very large ones, and therefore this section exists.

+

The claim that “Reticulum is not open source” is the foundation of the takeover narrative it so often accompanies. The sequence is always the same:

+
    +
  • First, declare the reference implementation illegitimate (“not really open source”, “owned by one man”, “not a real community project”)

  • +
  • Second, conclude that it is therefore acceptable - even necessary - to replace it.

  • +
  • Third, present the replacement, which is (conveniently) often the speaker’s own machine-generated clone, as the legitimate heir.

  • +
+

This is not speculation about motives; it is the documented structure of the campaign examined in A Movement Of A Dozen.

+

The “not open source” claim is the legal-ideological battering ram of that campaign. It is recycled, in article after article, in forum after forum, because it works on people who assume that a committee’s definition is the same thing as the truth.

+

It is also worth stating the other obvious fact: None of these critics have ever shown that the Reticulum License restricts them. They do not build weapons. They are not training models on the codebase. They are free, in every practical sense, to use Reticulum exactly as they would under MIT or GPL. Their objection is not to a restriction on themselves; it is to the mere existence of a license that states a moral position they disagree with, or which they can use as leverage for a different goal entirely, and to the institutional fact that it does so outside their system of approval and control. The complaint is not that the license makes them unfree. The complaint is that the license is free of them.

+
+
+

The Distribution Argument

+

A recurring companion claim is that RNS is not properly “distributed”, usually deployed as “it’s not packaged as a .deb” or “it’s not on package manager X”, with the implication that it is somehow unavailable or inaccessible, or hard to install on a given system.

+

This is simply false, and it has been false for years. The reference implementation is available on practically every platform and architecture with a single command (pip install rns). It is packaged in the Arch User Repository, in NixOS, and in a range of other distribution channels, community-maintained and official. It can be installed, updated, and kept current over Reticulum itself - the network transports its own software updates. It is used on more than a hundred thousand devices worldwide, is embedded in over a hundred other packages and applications, and carries terabytes of traffic every day.

+

The claim that Reticulum needs a .deb to be “really distributed” mistakes the mechanism for the goal. The goal is that people can obtain and update the software easily, everywhere, on their own terms, and distribute it themselves, both offline, online and over Reticulum with full cryptographic verification of the install packages, without any central infrastructure.

+

That goal is met to an excellence that few software packages can speak of, and met in a way that does not pin the project’s release cadence to the review cycles of distribution maintainers, which is an achievement, not a bug.

+

A project like RNS that updates continuously, sometimes daily, and has a track-record of shipping security updates mere hours after issues are discovered, would be crippled by packaging that makes every change wait months for approval. The distribution complaint is a strawman generated for the occasion. It has been answered, in public, many times; it is repeated anyway, because the people repeating it are not counting on facts - they are counting on the reader never having heard the answer.

+
+
+

On The Institutions, In Fairness

+

None of the above is hostility toward the Open Source Initiative or the Free Software Foundation as institutions, nor toward the individuals who have dedicated decades of work to them. Their contribution to the world of software is enormous, and this document does not dispute it. What is disputed is a specific claim of authority: That “open source” is a term whose meaning is reserved to a committee’s approval, and that a license which does not submit itself to that approval is therefore not open.

+

That claim of authority is not in Reticulum’s interest, and it is not in the interest of the people the movement claims to serve. The current legal and technological landscape - the machine-appropriation of the commons, the weaponisation of “prior work” generation, the erosion of human agency by synthetic systems - was not anticipated by the DFSG of 1997, and the institutions have not, as of this writing, produced any meaningful answer to it. The choice, as it was put at the time of the license change, is whether developers should sit back and wait for a solution from a committee that “may or may not ever materialize, before the entire foundation we stand on has been eaten away”.

+

Reticulum’s answer was to act. If we had waited, it would have been too late.

+

If an OSI-approved license existed that expressed the same constraints - and did not impose the far more severe restrictions of copyleft - the project would have used it. None such exists. That is not Reticulum’s failure. It is the measure of what the definition is missing.

+
+
+

What “Open” Means Positively

+

For anyone who wants the positive statement rather than the rebuttal, Open Source, in this project’s understanding, means:

+
    +
  • The source code is available, to everyone, without charge

  • +
  • Everyone may use, copy, modify, merge, publish, distribute, sublicense, and sell the +software

  • +
  • No one is discriminated against as a person - developer, user, community, or project

  • +
  • The protocol itself is dedicated to the public domain, where no one can own it

  • +
  • And the single, plainly stated condition of the license is that the work shall not be +consumed to harm human beings, or ingested to replace the humans who made it

  • +
+

If that is not “open” by a definition written in the 1990s, then the definition is the thing +that has failed - not the software, and not the people who use it.

+

Open source means open source. It was true before the committees existed to certify it, and it will remain true after they are gone.

+
+
+
+

Assistance Versus Machine-Substitution

+
+

False Dichotomy

+

The public discussion around machine learning and software development has been derailed, by the loudest voices on both sides, into a farcical fight between “AI enthusiasts” and “AI haters”.

+
+

Both positions are absolute caricatures.

+

The fight is beside the point in the ways that matters most.

+
+

It is not an accident, but a very conscious choice that the initial analysis of the Prns case examined herein, and this very chapter, were themself produced with the assistance of a machine-learning based generative system.

+

Specifically, it was generated using lc managing a Q8_K_XL quant of DeepSeek v4 Flash running in the llama.cpp inference engine. The main context base used to stabilize, ground and inform the generative environment consisted of approximately 100,000 tokens of text material that I personally thought out and wrote (by hand), then archived and organized, over the last eight years.

+

If you know my writing, and have a hard time discerning where this chapter is me directly, typing manually, and where it is the machine output, it is because of two things: Almost every line in this chapter was either directly edited by my hands on the keyboard or typed by me, and the text corpus that informed the process is genuinely me - my thoughts, written by me, over a period of years.

+

The chapter was produced this way deliberately and openly, under a software framework I designed and wrote, with the human directing the inquiry points, flow of investigation, structure of the outputs, contents of every section, making the editorial decisions, reviewing the conclusions, painstakingly adjusting every line, and taking responsibility for the final claims presented, with the goal of reaching a higher level of synthesis and symbolic density than I could have achieved without that assistance.

+

The tool was used as tool, both to structure and produce a complex chapter, and to inspect a repository so preposterous in size, commit velocity and nonsensical wording that it barred any purely human inquiry.

+

As such, the position is hereby, by personal example and demonstration, stated clearly:

+
    +
  • Technological assistance is not the problem

  • +
  • It was never the problem

  • +
  • It is the opposite of the problem

  • +
+

The problems are substitution and usurpation: The perverse process in which the machine becomes the author of choices, and the human becomes the facade of software, while expecting “reciprocity” or recognition for deeds they never performed.

+
+
+

The Line

+

The exact distinction can be reduced neither to how many lines of code a machine produced, nor who pressed the keys. The final distinction has to rest on who, or what, the real agent of the work is.

+
    +
  • Assistance is when the human retains the full seat of agency: The human decides what to build, judges +what is correct, rejects what is wrong, understands what is shipped, and can answer for every single line of it. +The machine writes, suggests, drafts, accelerates meaningfully and within reason - but every choice that survives into the +final work is a choice the human made consciously, and understood - or grew to understand - the consequences of.

  • +
  • Substitution is when the machine becomes the agency: the machine decides what to build, +decides what is correct, iterates on its own errors, generates at a scale and speed no single +human can follow - and the human’s role is reduced to providing the name, the account, the +signature, and the marketing launch.

  • +
+
+

The Line can be stated as a single test, and this is the same test that has always separated authorship from couriership: Can the person whose name is on the work answer for it fully? Not “can they describe what it does” - can they account for why it is the way it is, line by line and decision by decision, and the history of how it came to be that way, under questioning, without machine assistance, including by people who know more than they do?

+
+

If they cannot, they did not author the work. They wore it, or in more severe cases, they stole it. And a courier who claims authorship is not a writer; they are a fraud.

+
+
+

What assistance looks like

+

Assisted work is recognisable, and recognisability is itself part of its value. It has the following observable properties:

+
    +
  1. The human can explain it. Under examination, the author can say why this choice was +made, what was rejected, and what they verified. The ability to explain is not a luxury; +it is the very demonstration of authorship. On a large project with many contributors this is partial in +practice - no one can explain every line of a large codebase - but the full capacity must +exist between the authors and the habit must be visible.

  2. +
  3. The human can, and does, reject machine output. An author who has never rejected the machine’s output is not +an author, but an open drain. Rejection is not a stylistic flourish; it is the +mechanism by which any work attains Quality. A record of decisions, including reversals and rejections, +is a sign of agency. A record without rejection is a record of assent-by-default.

  4. +
  5. The human’s judgment is directional. The work contains the human’s actual choices; +things the machine would not have decided on its own, which the human can defend on their +merits. This directionality has many names in engineering: Design, architecture, taste, +judgment. Where it is absent, the work has the uniform, self-consistent texture of +something that was never doubted, and doubt is exactly what anything important requires.

  6. +
  7. Provenance is not concealed. Disclosure of how the work was made is not a legal +requirement in every jurisdiction; it is not even always a practical requirement. But it +is a statement that matters. A project that discloses its process - +including its use of machines - is telling the truth about the relationship between the +human and the work, and that is a property users are entitled to know. Concealment of +provenance is not a stylistic choice; it is deception, made by someone who knows what the +record would otherwise show.

  8. +
  9. The human stands behind the failures. When assisted work fails, the human can say: Yes, I +chose this, under these assumptions, here is why, here is what I got wrong, here is the fix. +That sentence is the entire contract between an author and the people who depend on their work. +A human who cannot say it - because the choices were never theirs - has nothing to offer anyone, and +is by definition entirely replaceable; anyone else could have pressed the same button.

  10. +
+
+
+

What substitution looks like

+

Substitution is equally recognisable, once the pattern is known:

+
    +
  1. Scope that no human could have authored. Output that +structurally cannot have been the product of human authorship, review, and judgment, for +example when the volume exceeds any reasonable human capacity within the span of the project’s life. +When the review capacity and the output volume are incommensurable, the output was not +reviewed. It was generated, then forgotten, and the record was signed blindly.

  2. +
  3. Uniform generation. The work carries no trace of a human’s changing mind. No style +drift, no contested decisions, no “we tried X and it was wrong, so we did Y”. That is, no +signs of actual development, growth and learning. Instead, endless, self-referential +refactoring, renamed abstractions, and the same fluent register in every commit, +every document, every reply. A human’s history shows the wear of judgment. +Pure generation shows the superficial polish of its absence.

  4. +
  5. Discovery by recursive regeneration. When errors are found, they are found by the machine’s own +subsequent runs, not by human scrutiny - and the findings are recorded as planned +“reviews” and “alignments” rather than as the corrections they are. This is the tell: A +machine editing its own previous output, while the edit is recorded as if it were a +scheduled milestone. That’s not review. That’s a continuous generation loop revising itself, +with the attempt of an illusion-preserving voice-over.

  6. +
  7. Laundered provenance. Theatrical concealment machinery: Commit hooks that refuse +attribution of machine generation, contribution policies that declare machine output +“yours”, processes that scrub personal traces from the history, fake identities in the +contributor list. All of these have one function: To make the record say what the “author” +wished had happened, rather than what happened. A project that builds such machinery is +not making a record of its work; it is using automated software to manufacture one.

  8. +
  9. Authorship by assignment. The human’s name is on the work, but the human cannot +answer for it - because the human did not choose any of it, and knows it. The name is not a +signature of authorship; it is a fraudulent claim of ownership over something the claimant did not +make and cannot explain. In every field that has ever dealt with such claims - art, +literature, invention, journalism - this has a name. That forgery is now cheap in software +makes it no more forgivable.

  10. +
+
+
+

Infrastructure Matters

+

For a hobby project, the distinction between assistance and substitution is a personal matter. For infrastructure - code that other people’s communications, safety, and freedom run on - it is a matter of life and safety, and any statement about this must be entirely unapologetic.

+

Infrastructure has one property that distinguishes it from almost all other software: While most of the people who depend on it cannot verify it themselves, it must be verifiable, auditable and open to human inspection, and be engineered in such a way that this is as frictionless and straight-forward as possible.

+

The reference implementation of Reticulum was designed this way, and continues to make that goal a primary one. While it is a complex piece of software, with an intricate array of interlocking and moving parts, the core parts of RNS, the entire Reticulum protocol implementation, the transport logic, the cryptographic primitive interfaces, is less than 15,000 lines of code. That line count even includes the rather extensive comments, incredibly detailed logging facilities and other choices that makes the code easy to read and understand for humans, and easy to operate, verify and debug. It took real dedication, and a lot of hard work to achieve that.

+

Exactly because not everyone can do this, it is a fundamental necessity for infrastructure software that it is designed and authored so that as many as possible can, and that the chain of accountability - who made it, who reviewed it, who answers for it - is held intact at every link. That chain is not decoration. It is the entire mechanism by which normal users decide to trust a system they cannot fully verify. The transparent foundations and the chain combined is the verification for most users.

+

Substitution breaks the chain both at the foundations, and at its load-bearing link: The human at the top can no longer answer, because they were never the maker. Unfortunately, the chain does not always fail visibly; often it fails silently, at the exact moment a question goes deep, or when routing fails subtly at a critical moment.

+

For the user, the result is not a project with a normal and humanly flawed author - it is a project with no author at all; a signature with no substance behind it, a name that cannot be held to account, and a body of work that nobody on earth can (or wants to) explain, defend, or fix in a crisis.

+
+
+

The Fluency Trap

+

It is worth understanding, briefly, why substitution is so attractive and so dangerous at once. Machine-generated output is fluent. It is confident, well-structured, and terminologically self-consistent. At the surface, and from the perspective of someone outside a given craft, it is indistinguishable from the output of a knowledgeable human. Fluency of this kind can be a useful property: It makes assisted work fast. But fluency is not understanding. It is the minimal conformal surface of understanding.

+

The danger is that the surface is exclusively where the substituter invests; for the simple reason that the surface is where most of the desired audience looks, and what yields attention to the project.

+

A human who can tell the difference uses the tool well. A human who cannot is being deceived through means they cannot detect from inside, namely through their own inability to account for the limits imposed by what they do not know.

+

This is why the most important quality for anyone working with systems like Reticulum is not speed, and not vocabulary, but the oldest engineering virtue there is: The honest, uncomfortable, terrorizing knowledge of what you do not know. The substitute never has it. The substitute’s operator, if they ever had it, loses it precisely the moment they accept the fantasy of the substitution process.

+

The tool is not the hazard, plain old human nature is. The tool is a mirror, and mirrors - as has been observed for rather longer than software has existed - show the truth only to those willing and yearning to see their own shortcomings.

+
+
+

Disclosed Assistance Or Laundered Generation

+

The contrast at the centre of this entire discussion can be made clearer with two examples, both of which are publicly accessible, both produced in the same year, by people using the same class of tools.

+

The first is this chapter. It was produced with machine assistance, openly: the structure was directed by the human, the material was assembled with the tool’s help, every conclusion, every line, every slight nuance of meaning and semantics was examined, edited, and accepted or rejected by the human, and the process described publicly - including the precise characteristics of the technological assistance framework used. The human can answer for every claim in these documents, because the human made the decisions the claims rest on.

+

The second is the project examined in the Prns case. It was produced by a machine, at a volume no human could review, and the authorship record was engineered to erase the machine’s role: A commit hook that refuses attribution of machine generation, a contribution policy declaring machine output the human’s own, a fictitious contributor identity, 637,000 lines of unreviewed code. The human cannot answer for the code, because the choices were never made by a human - only the conformal surface of the presentation was.

+

The same tool class. The same technology. Two diametrically opposed relationships to truth and responsibility. The difference is not the tool. The difference is the presence or absence of the human as the agent of the work - and the honesty or concealment with which that relationship is recorded.

+

Assistance leaves the human as the agent and the commons as the source from which the human works and can grow. Substitution removes the human from the loop and converts the commons into fuel for the thing that seeks to replace them, or usurp their work for the profit of the few, human atrophying in the process.

+
+
+

The License In This Context

+

The Reticulum License, examined in What The Reticulum License Is, draws the same line, at the level of the law. Its AI condition does not forbid the use of machine-learning technology to assist development - no reading of the license could support that, and no one associated with this project has ever claimed so. What the condition forbids is the appropriation of the work into the machine itself: The ingestion of the commons as raw material for synthetic replacement, and the concealed fabrication of “prior work” that would bury the real thing.

+

As also noted in Copyright & The Two Legal Layers, plain old copyright law already protects against the case where a process copies the reference implementation into a machine, produces a transformed derivative, and then claims “Copyright, [name of the process operator]”, with no human able to account for the creative decisions in the result. That is simple, petty theft, as it always has been.

+
+
+

The General Principle

+

In these regards, the position of this project can be codensed to something relatively concise:

+
    +
  • Machine assistance in human learning, development, and creation is accepted and useful. +It is not a shameful secret; but it is a tool that needs knowledge, training, understanding, +and great care to use. It should not make anything easier or more fun, it should make the +results better, more carefully considered, and arrive at higher levels of synthesis, not +produce endless streams of code churn.

  • +
  • The line is crossed when the human stops being the agent of the work. When any output is +accepted that the human cannot explain, produced at a scale the human cannot review, or filed under a record +where the human has arranged to conceal the fact.

  • +
  • The line is crossed, when a human claims authorship of work they cannot +answer for or has usurped. Credit follows the ability to answer. It has always worked that way, and +machines do not change the rule - they only make it cheaper and more tempting to break.

  • +
  • The people who depend on infrastructure have the right to know which side of the line +the code they run was made on. That knowledge is the only verification most of +them will ever be able to perform.

  • +
+

Use assistance, by all means, and learn, but don’t substitute. And never sign what you cannot answer for.

+

Somewhere, within the general shape of the conceptual framework outlined in this section, or realistically, a more refined variant of it, I do believe there is the potential of the beginning of a constructive outcome to the immense challenge we are faced with as a species in regards to these problems.

+

At the same time, I reserve my right to revert that position to Butlerian Jihad without prior notice. We are on a knife’s edge, and you know it just as well as I do.

+
+
+ +
+

Evaluating a Reticulum Implementation

+
+

The Intention Of This Guide

+

Very few user of network infrastructure can verify the software they run. This is true of the reference implementation as well, and it is precisely why it was engineered the way it was: the entire Reticulum protocol implementation - the transport logic, the cryptographic interfaces, the routing - is less than 15,000 lines of code, including its extensive comments and detailed logging. The reference is designed to be readable by a human in a reasonable sitting. That is a deliberate decision, and it is the standard against which every other implementation should be measured: An implementation that asks for trust while being structurally unreadable is asking for the absurd.

+

Because most users cannot verify the code directly, the evaluation of the project is the evaluation of the software. The framework below exists so that this evaluation can be performed in minutes, by anyone, without expertise - and so that each new “implementation” does not require the kind of full investigation that would otherwise be if not impossible, prohibitevly expensive.

+
+
+

Two Questions That Resolve Most Cases

+

Other considerations in this guide is further corroboration. These two questions allow you to decide the case quickly in most instances, and they should be asked first.

+

Question 1: Does this speak the protocol, or was it just generated from the reference?

+

The copyright and license realities, described in What The Reticulum License Is, is the legal foundation of this distinction. The protocol is public domain: A genuine clean-room implementation, reasoned out and written by humans, is free and welcome, and owes nothing to any license. But an implementation that was directly generated from the reference - reproduced by a copy process, whether manually or through a machine or software - is a derivative of the licensed work, and is subject to both the license’s conditions, and to the ordinary copyright law examined in Copyright & The Two Legal Layers. A primarily machine-generated copy without substantial human creative input is not merely unlicensed; it is a copyright violation that would exist under any license at all.

+

Ask: Does the project say where its protocol knowledge came from? Does it credit the reference implementation, or claim “ground-up” status while its own history shows continuous ingestion of the reference’s source? Does its license carry the original copyright notice? The answers tell you, within minutes, which of two very different kinds of project you are dealing with.

+

Question 2: Who, or what, is the agent of the work?

+

This distinction, established in Assistance Versus Machine Substitution, is the trust foundation of everything else. Is there a human who decided what to build, judged what was correct, rejected what was wrong, understands what was shipped - and can answer for it, line by line and decision by decision, without machine assistance? Or is the machine the agent, with the human’s role reduced to the name, the account, and the signature?

+
+

This test has a sharper form: would the project be meaningfully different if someone else had pressed the button? If the answer is no - if any person could have been the signature and nothing would change - then the “author” is not the agent of the work. They are its facade, and the project is, in the most literal sense, worthless and unowned.

+
+

A project with no owner is a project no one can answer for, and infrastructure with no one to answer for it has no place carrying other people’s traffic.

+
+
+

Other Signals To Look For

+

Once the first two questions are answered, the following signals determine the verdict. None is alone decisive; together they form a pattern that is difficult to fake in the directions that matter.

+
+

Provenance and attribution

+
    +
  • Credit to the reference. Does the project name Reticulum’s reference implementation +in its README, its website, its licenses, and the code? Does it present itself as a port +or as a “ground-up” origin story? Absence of credit, in a field where every implementation +owes its existence to the reference, is not an oversight; it is a decision.

  • +
  • License compliance. For a derivative, the license conditions apply: the copyright +notice and permission notice in all copies and substantial portions, the harm condition, +the AI-training condition. A project whose license file claims a fresh copyright in the +operator’s name, over work that was generated from the reference, has failed the minimum +bar of honesty before any code is read.

  • +
  • Disclosed provenance. Is the use of machine assistance stated openly, or does the +project maintain machinery to conceal it - commit hooks that refuse attribution of +generation, contribution policies that declare machine output the human’s own, scrubbers +for personal traces, fictitious contributor identities? The first is the mark of a human +using a tool. The second is the mark of a record being manufactured.

  • +
  • The author’s history. Is there a prior record - projects, contributions, a body of +work that a person can look at and reasonably assess? A sudden, fully-formed “decade of experience” +appearing from nowhere, attached to a project of unprecedented scope, is a story that +contradicts itself.

  • +
+
+
+

Agency and answerability

+
    +
  • Who answers the questions? When technical questions are asked, does a human answer +with substance - going deeper, explaining trade-offs, admitting uncertainty - or do +answers deflect to process (“the CI verifies it”, “the proofs prove it”, “the audit +covered it”)? Are the answers themself machine generated? Deflection to process is +the substitute’s answer pattern: It names the machinery instead of the reasoning.

  • +
  • Velocity commensurate with authorship. Is the output volume compatible with human +authorship, review, and judgment? An implementation ten (or 42!) times the size of the reference, +produced in a fraction of the time by a single person, is not evidence of brilliance; it +is evidence of unchecked generation. Churn is part of the same signal: A project that +deletes half of everything it adds is not building; it is looping.

  • +
  • Signs of development, growth and learning. Do reversals exist? Contested decisions? +“We tried X and it was wrong, so we did Y”? Humans change their minds, admit mistakes, and +leave the wear of judgment in their history. Pure generation shows “the polish of its +absence”: uniform register, endless renaming, and errors discovered by the generator’s own +later runs, recorded as if they were planned milestones.

  • +
  • Standing behind failures. When something is wrong, does the human say “I chose this, +here is what I got wrong, here is the fix”? Or do corrections arrive as process language, +with nobody accepting that a decision was even made? A project whose history contains no +first-person acceptance of error contains no author.

  • +
+
+
+

Engineering reality

+
    +
  • Honest benchmarks, or none. If performance is claimed, is the baseline real - stock, +current, interpreted RNS, on the modern interface, at equal policy, with methodology +published in advance and reproducible by anyone?

  • +
  • Interop with reality. Is compatibility verified against the current reference +implementation - on real hardware, including the radio and serial interfaces this +protocol family lives on - in both directions, over long transfers, uptimes and edge cases?

  • +
  • The readability standard. Can a competent human read the core of this implementation +in a reasonable sitting, the way the 15,000-line reference can be read? Was human +readability a stated design goal, or an afterthought? A project that cannot be inspected +is a project asking for trust it has not earned and will never attend to.

  • +
  • Nonstandard inventions. Does the project “improve” on the protocol with its own +modes - new channel behaviour on shared spectrum, new rendezvous mechanisms, new crypto, +“post-quantum” replacements, “turbo” variants? Inventions that change behaviour on a +shared network are not features; they are forks of the airwaves, imposed on every other +node that shares the medium. A project that invents on top of a protocol it has not yet +correctly implemented is not advanced; it is dangerous to its neighbours.

  • +
  • The public record. The commit history is public. Read it.

  • +
+
+
+

Network citizenship

+
    +
  • Honest presence. Does the project identify itself honestly on the network, or does +it masquerade as something it is not?

  • +
  • Coexistence. Does it respect the shared medium and network conventions? A node that +is a bad neighbour on the spectrum is a hazard regardless of how well its code works in isolation.

  • +
  • Community participation. Does the author participate in the community as a member - +answering questions, contributing, learning - or only appear to advertise? The second is +not participation; it is exploiting the community as a broadcasting target.

  • +
+
+
+

Monetary and influence signals

+
    +
  • Money under the claim. Donations, funding, or commercial offers premised on claims +like “89× faster” or “formally proven” convert false marketing into a different category +of problem. When money changes hands on the strength of fabricated measurements, the +stakes are no longer theoretical.

  • +
  • Tokens and “investment” vehicles. Any implementation that surrounds itself with a +crypto token, a “coin”, or an investment pitch should be treated as what it is: A project +whose primary purpose is to earn the controller a profit, not open networking.

  • +
  • Marketing-first ordering. A polished website on day three, a twelve-language marketing +presence, a “benchmarks” page and a “get started” funnel existing before the protocol works +is a massive red flag. Real builders ship, then talk. The inverse order is the signature of +a project whose goal is attention.

  • +
+
+
+
+

The Conformal Surface

+

One warning before the synthesis. When you evaluate any project, assume - as a working hypothesis - that its surface is an investment. The marketing, the design, the badge collection, the “proof records”, the fluent and confident prose: This is exactly where substitution invests, for the simple reason that it is where the audience looks first. Fluency is the minimal conformal surface of understanding, and the surface is not evidence of anything except that the author wanted to look convincing. If you find yourself impressed by the surface before you have asked Question 1 and Question 2, you are doing the evaluation in the order the substitute operator hoped you would.

+
+
+

Possible Verdicts

+

The framework proposed here can yield three different verdicts:

+
    +
  1. Meets the standard. A named human who can answer for the work and demonstrably does; +provenance disclosed; attribution given; honest benchmarks; interop +demonstrated against current, real RNS on real media; readable code; a maintenance +history that shows growth and learning. This standard is not high. It is what the +reference implementation has met, in public, for over a decade, and it is what any +project that wants other people’s traffic should be willing to meet in turn.

  2. +
  3. Experimental, but honest. A project that clearly labels itself as in-progress and +experimental (“do not use this yet”, in plain words, as the first thing a user sees) +discloses its provenance, credits the reference, and is being developed in the open by +humans who answer questions. Such projects should be encouraged. They are how the +ecosystem grows, new ideas are tested, and the framework above is designed to make an +honest experimental project easy to recognize, not hard.

  4. +
  5. Does not meet the standard. Unanswerable authorship, concealed provenance, fabricated +measurements, invented protocol behaviour, absent interop, marketing ahead of substance. +Such projects should be treated as unproven regardless of their surface, and as hazards +if they invite users onto shared networks. The community owes them exactly the +skepticism they have earned, and not a moment of engagement beyond that; the network’s +time is better spent elsewhere.

  6. +
+
+
+

These Standards Are Reasonable

+

I’ll close this guide by stating what these standards are not: They are neither a demand for perfection, nor a ban on machine assistance. Assistance is useful, when it is used to arrive at higher levels of synthesis than unaided work. It is not a requirement that an implementation be a clone of the reference; neither is it a requirement that it invents everything from scratch or aspires to be a “clean-room” implementation. Good implementations of the protocol are very welcome, however they come, but working on one requires serious work, considerable skill, and deep competence.

+

The reference implementation has met this standard for years, and its users know what that looks like.

+
+
+
+

The Movement Of A Dozen

+
+

Presentation, Elongated

+

Whenever Reticulum defends itself, its license, or its community - or simply continues to exist - a familiar chorus appears. The register is always similar: concern. Concern about the direction of the project. Concern about its license. Concern about its governance. Concern about its “bullying” of “good-faith contributors”. Concern about the future of the ecosystem at the hands of a single maintainer. The chorus speaks in the plural, presents itself as a body of independent voices, and insists, with some frequency, that it is… not alone.

+

The implicit claim under examination in this section is that there exists a movement of concerned individuals, spread across the ecosystem, all worried about Reticulum, and therefore (for some reason) deserving of a place at the table of decisions.

+

A resolution of this claim requires one step: Count them.

+
+
+

Headcount

+

This “movement” does have a headcount. It is not in the hundreds, and it is not in the dozens. It is a small number of people who appear, in various combinations and under various names, in the following roles:

+
    +
  • Creators of the machine-generated “Reticulum implementations” examined in this chapter.

  • +
  • Creators of articles praising those implementations and lamenting the state of the +reference, its moral shortcomings, its unavailability or lack of something it already has.

  • +
  • Commenters “defending” the implementations when they are evaluated reasonably and critically, +most often by attempting simply to derail the discussion.

  • +
  • Critics of the Reticulum License on “open source” grounds.

  • +
  • “Concerned community members” objecting to the maintainer’s conduct.

  • +
  • Campaigners on online platforms; and

  • +
  • In some cases, a single individual performing several of these roles at once, under +different names, in the same week.

  • +
+

The overlap is well documented at this point, across time and different platforms. The same phrasing, the same arguments, the same links, the same reactive reflexes, the same handful of accounts appearing in the same threads at the same moments. When the sockpuppets are unmasked (and they frequently unmask themselves) the cast does not grow, but rapidly shrinks.

+

This is the most interesting single fact about the “movement”: It isn’t one. It is a synthetic cast, held together mostly by LLM-glue, reddit handles and hysteria. A cast is not a constituency. It performs; it does not represent. The difference matters quite a bit, because a great deal of this “movement’s” imagined power comes from the assumption that the plural form is actual evidence of plurality. If that sentence seemed opaque, notice how many times a statement or article uses “we” instead of “I”, and it will be less so.

+
+
+

Recycled Wine, Fermenting

+

The cast is not only small, it is also, by any evidentiary standard, forgetful. Every major claim this “movement” advances has been advanced before, answered in public, with evidence, and often years ago - and is then advanced again, unchanged and completely ignoring any rationale or evidence presented previously (to the same people), as if the answer had never been written.

+
    +
  • The license argument. Reticulum is “not really open source” because its license is not +approved by a particular orthodoxy. This is answered (now in a new and updated version, for the +fifth time) in full in Open Source Means Open Source. It was also +answered in public, at length, at the time of the license change - including the +arithmetic of who is actually restricted by which license. It is repeated ad infinitum anyway. +Quite a conversation starter, apparently.

  • +
  • The distribution argument. Reticulum is “not properly distributed” because it is not +packaged as a .deb or on some favoured catalogue. Reality: It is available on practically every +platform with a single command, packaged by the community in a wide range of channels, and +capable of updating itself over its own network. The argument has been answered; it is repeated.

  • +
  • The “stepped back” narrative. When the primary mirror of the project moved away from +a public internet platform, it was spun as the founder leaving for good, or now taking on dictatorial +powers, or abandoning his creation, or any variation or nonsensical combination thereof. +Those spins always center around justifying that a vaccuum now needs to be filled. +There was no such vaccuum. The narrative is repeated in various forms whenever convenient.

  • +
  • The enclosure narrative. The license is reframed as a “power grab” or an “enclosure” +of the commons - as if a license whose protocol is public domain and whose conditions +restrict only harm and appropriation were a form of enclosure. The most recent (and mostly incoherent) +expression of this narrative is, once again, fluent, polite, and factually hollow. The +bizarre arguments supporting the “article” include: Defunct and abandoned forks presented +as living, community forks bearing the very Reticulum License mislabeled as AGPL license vehicles +(created by “concerned users”), companion app forks correctly retaining the Creative Commons +licensing used as further evidence of the same and completely abandoned projects propped up +as being “the ecosystem”. Another case of LLM generated nonsense that the “author” didn’t bother checking. +The intent is clear here, simply produce more mass of the bullshit, so it can be further +referenced, regurgitated and linked to.

  • +
  • The “bullying” narrative. Whenever the community declines to treat manufactured +controversies as legitimate, or calmly documents the falsity of claims, or (Lord forbid) +moves a forum post for violating clearly stated forum rules, +the response is the same: The documentation is “bullying”, the community is “excluding” people, the +maintainer is “unprofessional”. In the most recent example, those accusations were made by someone who, in the +same week, publically called for the Reticulum maintainer’s “removal from the equation”, forged a moderator’s +username, attempted to drag unrelated individuals into the campaign, and presented a new +round of outright falsehoods. Contrary to popular belief, the accusation of incivility +is not the last resort of the wronged; it is the standard reflex of the exposed.

  • +
+

None of the “arguments” engages the answers given repeatedly, and extensively. That is the point, and the strategy. The arguments are not produced for the purpose of being engaged; they are produced for the purpose of being repeated - the same wine, poured into new bottles, on a cycle. Each cycle is short, cheap to produce, and (thanks to freely available fluent text generation) now nearly effortless. The intended audience is not the community, which has heard it all before. The intended audience is the newcomer, who has not.

+
+
+

The Method of Madness

+

The method behind the pattern is consistent and simple enough to be described precisely:

+

Bullshit asymmetry

+

Producing a fluent, plausibly-sourced smear is now the work of minutes. Refuting it to the standard this manual demands is the work of days, and the refuted smear is replaced by the next one within the week. This asymmetry isn’t just a fine point of the campaign; it is the campaign. The goal is exhaustion - the slow conversion of the community’s time and attention from building to defending.

+

Weaponized concern

+

The register of the campaign is almost always the register of solicitude: “we are worried about the ecosystem”, “we just want what is best for the community”, “this is about the future of the project”. The concern is directed, without exception, at the things the campaign wants changed, and the change it wants is always the same: The replacement of the reference’s authority with its own. Concern is the costume; capture is the choreography. It is the oldest form of cheap power grab in the book.

+

Event seizure

+

Any event - a license change, a platform move, a forum moderation decision, a subreddit closure, a security notice, even the most banal messages from maintainers or known contributors - are seized, stripped of their actual context, and re-narrated as evidence of the same pre-written story. The subreddit that was closed after its moderator vanished and ceased moderating (according to prior agreement with said moderator) becomes “the maintainer shutting down dissent”. Moving away from a highly centralized online platform becomes “the founder retreating”. The license becomes “the enclosure”. The pattern is so reliable that the story could be pre-written by a lightly mechanized quill; only the date changes. The actual real-world context of these events is documented, in public, in each case; the re-narration proceeds regardless.

+

The legitimacy circuit

+

The campaign invests heavily in the places where legitimacy is minted: Conference talks, blog platforms, social threads, and forums - presented as if these appearances constituted some sort of ecosystem-wide groundswell rather than the same dozen people moving through the same circuit. The LLM-generated articles cite the LLM-generated ports; the ports are praised in the articles; the managers of the ports spread the articles, and echo them on the forums and internet platforms; the conference presentations cite the forums. Random bypassers with the need for a cause watch the conference presentations and take on the holy duty of Internet Soldier. The circuit is closed, self-referential, and (to a reader encountering it fresh) convincing. It is also, entirely, a loop of bullshit.

+

The prior-work minefield

+

The machine-generated implementations have a consequence beyond attention: They flood the space with fake “prior work”. The effect, as the license discussion predicted in the beginning of 2025, is the creation of a minefield of sloppy repositories that can later be matched against any genuine project, and attempt to claim prior art, or even worse: Dissuade actual, honest developers or builders from taking up a real project they might have succeeded with, because they now believe it has already been done. Just as importantly, it also buries real efforts under machine-generated noise. The machine-ports are not failed attempts to contribute. They are (disregarding intentions, but effectively) the campaign’s long game, deployed as inventory.

+
+
+

A Persistent, But Fragile Triad

+

This chapter as a whole has documented three fronts: The legal-ideological attack on the license (Open Source Means Open Source), the substitution and usurpation pattern in machine-generated implementations (Assistance Versus Machine Substitution), and the takeover narratives examined in this section. They are three fronts of the same operation, run by the same cast.

+
    +
  • The license attack and other urgency-engineered narratives are the cover: They supply +the ideological justification for treating the reference as illegitimate, and needing replacement.

  • +
  • The ports are the inventory: they supply the “replacements” that the narrative claims +the ecosystem needs.

  • +
  • The takeover narrative is the objective function: the repeated, persistent, escalating claim that +the reference should be replaced, and that the speakers themself are the natural heirs.

  • +
+

Each front depends on the others, and all three depend on a single, fragile assumption: That their audience cannot count. Restore the count, and the charade collapses into what it is:

+

A small group of people, obsessively orbiting a technology they did not build, synthetically producing the +appearance of a constituency they do not have, in service of a takeover they cannot justify.

+
+
+

What The Pattern Is Not

+

It is important, to also say what this pattern is not, exactly because the campaign depends on being mistaken for such things.

+

It is not criticism

+

The Reticulum community has always had lively, rigorous criticism - of decisions, of priorities, of direction - and it has always engaged that criticism on the merits, and changed course and development priorities many times. The license discussions at the time of the change were extensive, public, and answered in full, including with the critics themselves. Core protocol decisions were always discussed and evaluated in the community. The complex coordination and execution of several protocol upgrades between a loosely organised group of developers, node operators and users have succeeded surprisingly fluidly. All of these are success stories that the “critics” always ignore. Real criticism engages the content and accepts evidence. The campaign engages nothing.

+

It is not a community

+

Communities build things, maintain them, and have skin in the game; long-term users, operators of nodes, authors of real applications, people whose traffic flows through the network every day. A community has a stake. The “movement” only has an agenda.

+

It is not a debate

+

A debate has parties who evaluate arguments and evidence, and as a function of that, the debate moves forward, perpetually. The campaign’s arguments, as shown above, are not designed to survive contact with answers, but to be repeated past them. You cannot debate a loop. You can decline to perform for it, though.

+
+
+

Intent & Consequence

+

While it would provide for interesting speculation, we do not need to know what the individuals in the cast intend, and this document will not speculate about their inner lives. People may believe their own narratives entirely, or partly, or not at all; the pattern is the same in any case, and the pattern is what matters here, since it is the exact thing that has been so insidiously destructive and resource wasting for the actual Reticulum project and community, ever since Reticulum was more widely discovered, popularized, and became a prime target for all sorts of grift known to man.

+

The consequences are very real:

+
    +
  • Time. The community’s scarcest resource is the attention of skilled people who actually build +and maintain the network. The campaign converts that attention into reactive defence, on a cycle +with no end.

  • +
  • Harm. Hastily machine-generated implementations, marketed as drop-in replacements and carrying +traffic onto shared networks, mislead users and can damage the network and its neighbours. +We, the actual reticulum community, all rely on these networks every day, and it is my belief +that we need to defend them. The fabricated measurements and laundered authorship examined in this chapter are not +editorial embellishments; they are the mechanism by which real users are induced to run +unverified, and often destructive software.

  • +
  • Erosion of the currency of trust. Every manufactured scandal, every fluently polite smear, every +fabricated “movement” debases the currency of trust and degrades it for everyone; +including, most of all, the honest projects that come after. This is deep harm, and +it is the primary reason this chapter exists.

  • +
+

Whatever the intent - profit, control, attention, or a simple, obsessive inability to stop - the mechanism is the same, and the response should be calibrated to the mechanism as a whole, not to the individual person acting as the current avatar for it.

+
+
+

Recognition & Response

+

For anyone who encounters the pattern fresh, here is a proposal on how to recognise it, and what to do about it.

+

Recognition: The pattern is recognisable in minutes, once the signs are known:

+
    +
  • Claims that have been answered before, repeated as if never answered.

  • +
  • The register of solemn concern applied, without exception, in one direction.

  • +
  • A severe allergic reaction to answering any questions posed.

  • +
  • A cast that is small, overlapping, and frequently anonymous, with the plural form doing the +work of plurality.

  • +
  • Sockpuppet theater: The same person or footsoldiers thereof appearing as several “supporters” +(and occasionally slipping up mid-performance).

  • +
  • Articles, ports, and forum threads that cite and reference each other in a closed loop.

  • +
  • The immediate, reflexive turn to “bullying”, “exclusion” and “toxicity” whenever a claim is refuted.

  • +
  • A complete absence of engagement with the substance of the answers given, and a complete +absence of stake in the network itself.

  • +
+

Response: A constructive response is one that is proportionate, and does not cost the +community its resources, sanity and dignity:

+
    +
  • Engage the content once, on its merits (if any), with evidence, in public, and then refer to the +existing records. The answers already exist; they do not need to be re-derived for every new +bottle of piss-sour burgundy served from a man behind the curtains. I will do my best to keep this +chapter up to date with such answers and records, for easy reference, but other great resources +exist.

  • +
  • Do not become part of the theater performance. The “movement” feeds on engagement in any form; +attention is its fuel, and outrage is as good as endorsement for them, if not better.

  • +
  • Do the headcount. When the audience is reminded that a “movement” is a dozen people +recycling answered falsehoods, its projected power dissipates. The power was never real; +only the audience’s own assumption of scale can make the illusion effective. A polished-looking +“ground up” implementation might look like the work of many people, but is most likely +just the result of an LLM looping on a laptop for a couple of months (this is weird, but it is +the reality we now live in). Four different users suddenly singing in unison may look like the +representatives of a broader sentiment, but is most likely the same person hiding behind the same keyboard.

  • +
  • Then, spend the saved time on the networks: On building real infrastructure, putting up nodes +and antennas, on real development, real maintenance, real coexistence, and on the people +who actually use Reticulum. The things that we can only do together, as humans. That is +what the fake “movement” cannot do, no matter how fluent and smooth its productions become.

  • +
+
+
+
+

Network Health & Coexistence

+
+

Substance Of The Networks

+

Before examining health, we should consider what is being protected. The networks are not a repository. They are not a website, a social presence, or a set of marketing pages. They are a habitat: A living commons of communication, carried by, from a catious estimate, an intermesh now consisting of over a hundred thousand physical devices, embedded in a plethora of applications and packages, transporting terabytes of traffic every single day - real messages, real coordination, real people - across radios, serial lines, phones, laptops, and backbone servers, in cities, places and ways that no other network reaches.

+

The protocol belongs to humanity; no one owns it. The network belongs to everyone on it, and its membership is defined by nothing other than participation: A node on a mast, a phone in a pocket, a server routing for its neighbourhood, a developer building on the commons. The network has no gatekeepers because it needs none; it is held together by the same physics and mathematics everywhere, and by a shared expectation of how members behave. That expectation - unwritten, unenforced by any central authority, and just as important as any code - is the subject of this section. The Zen of Reticulum calls the software a habitat. A habitat is healthy or unhealthy as a whole, and the health of this one is decided, every day, by the people who live in it.

+
+
+

Health Is A Property Of The Whole

+

A network is not made healthy by the excellence of any single part. It is made healthy by the behaviour of every part on the shared medium, and how they interact. And the shared medium is the point. When your node transmits, it transmits into the same spectrum, the same line, the same time, the same mathematical address space, the same bandwidth that its neighbours depend on.

+

The network cannot be certified by any single project’s claims. A node that is a bad neighbour, that invents its own channel behaviour on shared spectrum, that announces without discipline, that spawns tens of thousands of links to scrape the network, that floods and retries without mercy, is a hazard to every node that shares its medium, regardless of how well its “creator” imagines its own code to work in isolation.

+

On a shared medium, “my software works” is not a complete sentence. The complete sentence is “my software works and coexists”. A network’s health deteriorates with its worst-behaved member, and every member has a responsibility to not be that member. There is no final, technical solution for this; the solutions are human.

+
+
+

A History Of What Works

+

Let’s recall, because it is the ground truth this entire thing rests on, that the coexistence model has worked - is working, right now, at scale. Reticulum’s protocol decisions have been discussed and evaluated in the community, openly, for years. Protocol upgrades have been designed, coordinated, and executed between a loosely organised group of independent developers, node operators, and users - and have succeeded, repeatedly, without any corporate board, without any central command, and without the collapse that the skeptics predict every second week (while screaming for GOVERNANCE). The reference implementation has been developed in the open for over a decade, by a maintainer who answers for it, fixes bugs or issues within hours of their discovery, and is set down in code deliberately kept small enough (the entire protocol implementation under 15,000 lines, including its comments) for a human to read, verify, and challenge.

+

This is the empirical baseline that every narrative examined in A Movement Of A Dozen conveniently ignores, in order to justify:

+
    +
  • The claim that the project is a one-man dictatorship

  • +
  • The claim that the community is excluded

  • +
  • The claim that the networks need saving from their own founders

  • +
+

The reality, documented and reproducible, is that a loose community of humans coordinates complex technical evolution without the apparatus the narratives insist is missing. The health of the networks is not a promise for the future; it is a demonstrated property of the past and present, under the leadership and community model that brought it into existence and navigated it through difficult decisions and situations over a decade. My job is to keep it that way, and you can be damned certain that I take it seriously.

+
+
+

The Role Of The Individual

+

The networks are built by physical acts and human coordination. You cannot prompt an antenna into existence. No model can string up a dipole, or stand in the rain aligning a radio, or coordinate with a neighbour three valleys away about who covers which repeater frequency, or sit down with a newcomer and explain why their first node didn’t announce. These are the acts that make a network organic - present in the physical world, resilient because it is real, valuable because it is human. The machines and technology we use are tools aimed at a well-defined, openly described goal. But the networks themself are composed of intentional human actions, and every node operator is infrastructure for other humans.

+

This has a corollary for the individual: You do not need permission, and you do not need to be an expert, to participate. Run a node. Help a neighbour. Ask questions in the community, and answer the questions you can. Build something small at first. The network grows by these acts, and they are the most meaningful ones - the things that can only be done together, as humans, in the physical world. The parasitic “movement” that haunts the peripheries of this ecosystem cannot do any of this. It cannot build a node because it does not exist, in any real connected and human sense; only people can, and people are precisely what a self-recurrent loop lacks.

+
+
+

The Place Of New Implementations

+

The future of the network includes more implementations - and they are welcome. This chapter is not an argument against implementing Reticulum. The protocol is public domain, by design, and the network is made stronger by genuine diversity: More good implementations, honestly made, mean more resilience, more experimentation, more people who understand the protocol deeply because they have built it themselves. That is the goal: For people to understand and own the technology they rely on. Not to spew out 600,000 line rust ports that fills no meaningful gap or purpose.

+

What the ecosystem needs, from every implementation, is the ordinary floor that Evaluating A Reticulum Implementation establishes, and that the reference has met for over a decade: A human who made it and answers for it; provenance disclosed; attribution given; benchmarks honest or absent; interop demonstrated against the real network; code a human can read. And it needs the one thing that costs nothing and changes everything: Honest labeling.

+

An experimental implementation that says, plainly, as the first thing a user sees: “This is in-progress, experimental, do not depend on it yet, but help if you can”, that is a gift to the ecosystem. It contributes, it invites participation, and it protects users.

+

The opposite, the polished “drop-in replacement”, does damage far beyond its own users: It dissuades the honest developers who might have built the real thing, because the polished slop persuades them the work is already done. That dissuasion is one of the quietest and most expensive harms in this entire affair, and the antidote is honesty at every project’s door.

+
+
+

Expanding The Commons

+

Coexistence, reduced to its essentials, is a short formula; the duties of membership in a network no one owns:

+
    +
  • Be honest. Say what you are, what you built, how you built it, and what you used to +build it. Label experimental work as experimental. Credit the work you build on, including +the reference implementation, in the licenses and in the prose. Concealment is not a +defence; it is a very clear diagnosis marker.

  • +
  • Be owned. Have a human who made the work and can answer for it. Use assistance, don’t +substitute. Never sign what you cannot answer for. The chain of accountability is the +community’s only verification at scale, and every link in it is a person, not a facade.

  • +
  • Be a good neighbour. Respect the shared mediums. Do not invent new behaviour in our +shared space and call it progress. The network belongs to its other members as much as +to you.

  • +
  • Verify against the network. Compatibility is a property demonstrated with actual nodes, +on actual media, against the actual current protocol, over a period of years, not 48 hours. +And not a claim pinned to an old snapshot over loopback.

  • +
  • Participate as a member. Ask, answer, help, build. Advertising at the community is not +the same as being part of it, and it is not the first thing you should do.

  • +
+

None of this is a high bar. It is the bar the reference implementation has met, in public, for over a decade, and the bar the ecosystem has adopted organically itself, successfully, through every protocol upgrade it has ever coordinated, and everything running on Reticulum today, that people actually use. It is not a new requirement; it is the existing, working culture of the networks, now written down so that newcomers can find it and so that those who would exploit us cannot claim they never saw it.

+
+
+

Defence Of The Commons

+

The networks need defending - not because they are under severe physical attacks (yet), but because attention, talent and resources is being stolen from them, trust is being mined against them, and its newcomers are being harvested by the machinery documented in this chapter. Defence, for a commons, has specific shapes, and it is not what the theater would like it to be.

+
    +
  • Defence is documentation: Records kept public, of what was claimed, what was +answered, and what turned out true.

  • +
  • Defence is a headcount: Calm, unexcited reminders that a “movement” might just be a dozen +people having a tantrum.

  • +
  • Defence is honesty in action: The visible, ordinary practice of the good behaviour +by the people who actually run the networks.

  • +
  • And defence is building: Every node raised, every page of real documentation, every +honest implementation, every new user helped into the community with the knowledge to know +what they are doing is more durable than any rebuttal, because it adds to the thing being +defended.

  • +
+
+

The theatre cannot keep up with a network.

+

It can only orbit it, while it recycles its own sour piss.

+
+

A lot of us rely on these networks every day. They carry our messages, our coordination, our friendships, and in some places, our safety. That is exactly why they are a target:

+

They are valuable, free, and very hard to shut down. The response is not to become aggressive. It is to be more of what the network already is: Real, open, owned, and shared.

+

Mark

+
+
+
+

Addendum A: The Prns Case

+
+

Purpose & Scope

+

This section provides a concrete example, which future evaluations can use as a template. Its purpose is not to be the last word on this particular subject, but to be an example of how the ideas in this chapter can be applied, and to make the next such examination easier.

+

The subject of this case study is Prns, a project published at the repository github.com/KenAKAFrosty/Prns, presented as a “ground-up implementation of Reticulum, written in Rust”, marketed as faster, safer, and more strictly tested than the reference, widely promoted with the claim of “up to 89× the throughput” of the reference implementation, and an “author” actively engaged in the tactics described in A Movement Of A Dozen on online platforms. The record described below is the project’s own, and sourced from its GitHub repository, analyzed locally.

+
+
+

The Project In Brief

+
    +
  • Time span. 3,374 commits between 2026-05-26 and 2026-09-12: approximately 110 days, +at a mean rate of ~31 commits per day. Monthly: 132 / 1,137 / 1,097 / 805 / 203.

  • +
  • Authorship. 3,252 of 3,374 commits (96.4%) are authored by a single account. A +second identity, “Prns Tests tests@example.test” - a fictitious identity on a reserved +domain - contributed 35 commits, every one of them website and marketing content.

  • +
  • Size. 3,519 tracked files; 1,983 Rust files; 636,226 lines of Rust; approximately +22.7 MB of Rust source; 69.5 MB of total repository content.

  • +
  • Scope claimed. A daemon (“drop-in replacement” for the reference daemon), embedded +firmware for three microcontroller families (including six ESP32-S3 board variants and +nRF52840), SDKs and bindings for nine languages, a browser-based node and web flasher, a +twelve-language website, a benchmark apparatus with its own publication and “proof” +pipeline, and a validation hub with oracles, fuzzing, mutation testing, and formal-proof +claims.

  • +
  • Marketing claims. “Ground-up implementation of Reticulum”; “up to 89× the +throughput”; “48× smaller peak-memory footprint”; “33× the energy efficiency”; +“Measured, not just claimed”; “Enforced, then audited”; “byte-for-byte wire parity with +the reference implementation”; “works with Sideband, NomadNet, MeshChat, etc.”; +“no_std (no alloc required either)”.

  • +
  • Status at the time of writing. Version 0.3.7; published version history begins at +0.3.0. The repository continues to receive commits.

  • +
+
+
+

Question 1: Is this a clean implementation, or was it directly generated from the reference?

+

The first of the two deciding questions from Evaluating A Reticulum Implementation is settled by the project’s own record. An actual clean-room implementation, reasoned out and written by humans, would owe nothing to any license. The data available shows clearly that Prns is not that.

+
    +
  • The founding state. The first commit, “Scaffold Personal Reticulum suite”, contains +the scaffolding of not one but two ports - personal-rns and personal-lxmf, the latter +being the reference’s companion messaging protocol - together with a daemon scaffold and +a 233-line founding document, docs/build-ethos.md. That document declares the project’s +goal as a “performance-focused drop-in-replacement for rnsd” and its governing principle +as: “Port the contract, not the implementation.” It further states directly to the +machine-loop, that “You owe the reference fidelity at exactly two boundaries: +The wire… The behavior. … Between those two boundaries, the model is yours”. +At this point, the very first commit, effectively the whole of the implementation design +and any relevant decisions are handed over to the LLM.

  • +
  • Continuous ingestion from the reference. 506 commits reference RNS or Reticulum +source behaviour; the word “parity” appears in 49 commit messages. Commits cite the reference +implementation’s own source locations (for example Transport.py:1367) when correcting +their own divergences and mistakes.

  • +
  • Byte-level fidelity as an explicit goal. Within 48 hours of the first commit, the +record shows a “crypto adapter - vetted primitives, byte-exact vs RNS 1.3.1”, and a wire +implementation matching the reference’s packet header layout. The project’s own +validation apparatus decodes wire vectors using the reference implementation’s own +packet parser, and the interop suite consists of real, stock-RNS peer nodes - that is, +the reference source itself, used as the ground truth against which this LLM output is +checked, and committed as accepted and verified after 48 hours of the project’s recorded start.

  • +
  • The marketing mismatch. The same record that documents all of the above describes the +project, publicly, as “a ground-up implementation of Reticulum” - while declining, on its +website, to link to the reference implementation at all: the entire tree mentions the +reference’s author in six files, and the website in none.

  • +
+

Conclusion: the project’s own history and commit record establishes that it was generated directly from the reference implementation’s source code, not reasoned out from the public-domain protocol. It is a derivative of licensed work within the meaning of the Reticulum License and general copyright law. The “ground-up” claim, which carries its entire legal and marketing posture, is disproven by the project’s own history.

+
+
+

Question 2: Who, or what, is the agent of the work?

+

The second deciding question is answered by the application of Assistance Versus Machine Substitution criteria to the project.

+

Scope that no human could have authored

+

636,226 lines of Rust in 110 days is approximately 5,800 lines per day, every day, including weekends - with 149 commits recorded between midnight and 06:00, and Saturday the single busiest weekday. No human review or decision capacity is commensurable with this volume; the review capacity and the output volume are structurally incommensurable, which is the definition of unauthored scope.

+

Uniform generation

+

The record shows no sign of human development, growth, or learning: No contested decisions, no style drift. Instead: endless renaming (in the first 48 hours: State → EngineState → TickInput → TickOutput), uniform fluent register in every commit, and the exact same, synthetic voice in code, documentation, and website copy.

+

Discovery by regeneration

+

Corrections arrived by the machine’s own subsequent runs, recorded as planned milestones. In early July 2026, a series of “core review” commits documented, in the project’s own words:

+
    +
  • announce-ID history “was unbounded per-slot growth” (54cc8d601);

  • +
  • interface announce limiting could “leak a sustained flood” (9d27af75c);

  • +
  • a “phantom-airtime leak” where frames “used to vanish silently” (4ed75ffdd);

  • +
  • Group-packet deduplication “which RNS does not do” - a behaviour the reference never had, +implemented and later removed (edd8e72be);

  • +
  • “both unwrap_or(&[]) arms were unreachable dead defaults” (74bea355e);

  • +
  • a benchmark crate “hasn’t compiled since” a prior rename, undetected for weeks because it +was outside the CI’s workspace (86240b027).

  • +
+

Earlier still: the record shows a “>1 MiB RNS-to-Prns interop stall” closed three weeks in +(cc4d524a3), and a known send-path hang shipped with the note “typed fast-fail a +candidate for later” (a010e6613).

+

Laundered provenance

+

The repository contains a committed commit-message hook (.githooks/commit-msg) that blocks any commit containing attribution for machine generation (“generated with claude/codex/copilot/cursor/gemini”, “co-authored-by”), with the explanation “The committer owns the commit”. The contributing guide is explicit: “AI tools … are welcome … what you submit is yours”, and describes the contributing population as “both human and automated contributors”. The fictitious “Prns Tests” identity completes the picture: A manufactured, unknowable contributor, used for marketing content.

+

Authorship by assignment

+

The human whose name is on the work cannot answer for it, because the choices were never made by a human, and only the general shape and constraints of the outward presentation was. Nothing in the project’s history shows an individual explaining a design decision, accepting a mistake in the first person, or going deeper under technical questioning; the record shows process language and marketing instead. Per the earlier mentioned test: any other person could have pressed the same button, and nothing would be different. The project is effectively unowned, and void of value.

+

By the criteria of Assistance Versus Machine Substitution, this is substitution. The machine was the agent of the work; the “author” was a facade.

+
+
+

The performance claims

+

The project’s central marketing claim - “up to 89× the throughput” of the reference - is also its most completely documented failure, because the project published the evidence of its own measurement. The apparatus, the results, and the problems are all on the record.

+

The claim

+

The README states “up to 89× the throughput”; the on-network marketing page repeats “up to 89× the throughput, 48× smaller peak-memory footprint, and 33× the energy efficiency of stock RNS 1.4.2”; the website’s front page carries the tagline “Measured, not just claimed”.

+

The apparatus

+

The reference is loaded through benchmarks/reference/compiled_reference.py, which installs pyximport and then asserts two things: that RNS.compiled == True, and that at least one RNS module was loaded from a native extension. The project’s own published “proof” records show exactly what those checks captured, on every platform:

+
aarch64-apple-darwin: .../RNS.cpython-313-darwin.so,  Cython 3.2.8, Python 3.13.13
+x86_64-unknown-linux-gnu: .../RNS.cpython-313-x86_64-linux-gnu.so,  gcc 11.4.0
+x86_64-pc-windows-msvc: ~/.prns-oc/lib.win-amd64-cpython-313/RNS.cp313-win_amd64.pyd
+
+
+

In every case the recorded native module is the top-level package only - RNS.so, nothing below it. Nothing named RNS.Transport, RNS.Destination, RNS.Packet, RNS.Link, or RNS.Resource ever appears, because nothing below the top level was ever compiled. Nobody bothered to check or verify anything here.

+

The machine output was simply taken for truth, and a full marketing strategy was spun and produced on it. “RNS 1.4.2 (compiled)” - the label used in every table, chart, and marketing page - is not a mode of RNS that exists, but the hallucinations of a machine, which the humans created a marketing strategy on. In reality, it is the old CRNS development shim, whose top-level-only, debug-oriented “compilation” is slower than plain interpreted RNS, and which was defunct for over a year before these benchmarks were published.

+

Interface choices

+

The harness writes the reference’s configuration itself (benchmarks/reference/participant_node.py): TCPClientInterface for the initiator, TCPServerInterface for the responder and both relay sides, with UDPInterface as the abstract wire. The reference was never given its modern BackboneInterface on any platform, forcing the slowest possible interrfaces. The interface selection is never mentioned in any methodology text.

+

The policy

+

The published default-policy tables record the asymmetry directly: Prns at 500 Mbps / 128 KiB TCP policy against the reference at 10 Mbps / 8 KiB - slyly footnoted as “preserves each implementation’s normal TCP policy” (in the case of RNS, a conservative default policy that was selected to prioritize coexistence on slower, shared links, requiring the user to dial it up to full speed if they knew what they were doing). Raw transport “throughput” ratios of 20.65× (Linux) and 38.84× (Windows) are therefore mostly policy, not engine.

+

The cross-host evidence

+

The published results show the same scenario producing wildly different ratios by host, and the variance is entirely in the reference artifact:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Host

Prns, single-packet

“Reference”, single-packet

Ratio

macOS (Apple M4)

37.4k/s

420/s

89.09×

Linux (i7-1260P)

25.3k/s

3.5k/s

7.19×

Windows (Ryzen 5 5600X)

30.8k/s

3.9k/s

8.00×

+
+

Prns is consistent (25–37k/s). The reference artifact collapses to different depths on different hosts, and the single worst collapse - 420 packets per second on macOS - is the cell selected as the global headline. The “89×” is not a measure of Prns; it is a measure of how badly the broken baseline happened to fail on one host.

+

For reality calibration: Stock, interpreted RNS 1.5.4 on an ordinary mid-range laptop, single core, sustains roughly 30,000 single-packet deliveries per second (including ephemeral-key decryption), ~175,000–280,000 packets per second in transit relay, and on the order of 10 Gbps at 16 KiB payloads. The project’s “compiled” artifact measured 420–3,900 packets per second for its single-packet scenario: An order of magnitude or more below stock interpreted RNS. The comparison being marketed was not “Rust vs Python”; it was “an implementation running under optimal conditions versus a mislabeled, broken shim on a slow legacy interface at a severe policy disadvantage”.

+

The equalized rows

+

The project’s own “1 Gbps policy” rows, in which both sides are explicitly configured identically, publish ratios of roughly 2.4–8.4× across all hosts and scenarios - still against the broken baseline, but nowhere near 89×, and consistent with the ordinary, uncontroversial observation that a native implementation tends to outperform an interpreted one in raw throughput. That point needed no fudging to make, and is banal.

+

Interestingly, though, it seems that Prns is really only marginally faster than a Python implementation, running in interpreted mode, on a single CPU core.

+

Assessment

+

The front page says “Measured, not just claimed.” The record shows the opposite ordering: claimed, and arranged to look measured. No methodology section anywhere states what “compiled” means, that it is a deprecated development shim, that it builds debug targets, or which interface the reference was given; the one statement of the policy asymmetry appears in a footnote of the results tables themselves. If they did not need to fudge it, they would have published the method clearly.

+
+
+

Overall Evaluation

+

Evaluated against the conditions of Evaluating A Reticulum Implementation:

+
    +
  • Provenance and attribution. Fails: The fake “ground-up” origin story; zero reference links +on the website; a single well-hidden link in the README; a license file reading +Copyright (c) 2026 The Prns Authors over work directly generated from the licensed reference; +no original copyright or permission notice anywhere.

  • +
  • Agency and answerability. Fails on every criterion of Assistance Versus Machine Substitution: +Unauthored scope, uniform generation, discovery by regeneration, laundered provenance, +authorship by assignment.

  • +
  • Engineering. Fails: The benchmark apparatus above; interop demonstrated only +against a pinned, outdated reference version over loopback while the marketing claims current +parity, interop failures with stock RNS; vendored prebuilt binaries and a republished fork +of an upstream crate (nrf-softdevice 0.1.0-prns.1) with no verifiable provenance; +committed WASM bundles.

  • +
  • Network behaviour. Fails: Invented spectrum behaviour and compatibility claims +about third-party applications of the reference ecosystem (Sideband, NomadNet, MeshChat) +that are not established by any evidence.

  • +
  • Monetary and influence signals. The marketing apparatus - website before protocol, +day-three twelve-language marketing, false benchmark headlines, “audited” and “formal proof” +claims - the conformal surface described in Evaluating A Reticulum Implementation: +is where this project invested.

  • +
+
+
+

Licensing Analysis

+

Applying the two legal layers established in Copyright & The Two Legal Layers:

+

Layer A - copyright infringement (license-independent)

+

The record shows a direct copy roundtrip: the licensed reference implementation fed into a machine, transformed, at a scale and cadence no human could review, with a license file asserting a fresh copyright in the operator’s name and no acknowledgment of the work the project was generated from. No substantial, new human creative input is demonstrated anywhere in the record - the founding document explicitly frames the design as an instructed port of the reference’s contract. A primarily machine-generated copy of a copyrighted work, not accompanied by demonstrable substantial human creative input, is a derivative work over which the copier holds no copyright, and a reproduction of which without the original author’s permission infringes the original author’s copyright. This holds under any license, MIT included. The operator’s copyright claim over the result is, on this evidence, not merely unsubstantiated; it is the absence of one, directly asserted in the project’s own writing.

+

Layer B - license conditions (Reticulum License specific)

+

Modern Reticulum - the current wire format, the AES-256-based link encryption, ratchets, the cryptographic machinery as it exists today - has been published under the Reticulum License since April 15, 2025, effective from release 0.9.4 and every release since. As a derivative of that work, the license’s conditions attach: The copyright and permission notice must be included in all copies and substantial portions; the AI-training condition must be honoured; the harm condition must be honoured. The record shows none of the notice requirements met, and a production process that consists of the licensed work being ingested into a machine and regurgitated, at industrial scale and cadence.

+

The cascading consequence

+

Prns is distributed claiming dual MIT/Apache-2.0 licensing. It is, however, a direct derivative of Reticulum-licensed work, and the claimed grant is therefore void. Every downstream project that builds on Prns believing it is MIT/Apache-licensed is building on a grant that does not exist. The users of Prns, and all software developers using it, have in effect, been placed under conditions they were never told about. The “ground-up” claim is not merely false; it is the sole load-bearing element of an entire licensing posture, and it fails spectacularly.

+
+
+

Consequences

+

The consequences of this pattern are examined in the following sections: The harm to users and to the network in A Movement Of A Dozen, and the human dimension in Network Health & Coexistence. The contribution of this addendum is narrower and intended as an instructive example: This is what a substitution project looks like, in full, on its own record. It is a reference example for Evaluating A Reticulum Implementation, and it demonstrates, in one case, most of the elements this chapter describes.

+
+
+

Verdict

+

Applying the three verdicts of Evaluating A Reticulum Implementation, this project does not meet the standard. It is not “experimental but honest” - it is not labeled as experimental anywhere; the first thing users saw was a polished marketing presence promising a finished, tested, drop-in replacement. It is a project whose central claims are fabricated (the performance apparatus), whose provenance is laundered (the authorship machinery), whose foundation is misrepresented (the “ground-up” story), whose core semantics were learned late and by regeneration, and whose operator cannot possibly answer for any of it. It is also a blatant copyright violation of the reference implementation.

+

The proposed conclusion, for users and for the network: Treat the Prns project as hostile regardless of its polished surface, and as a hazard insofar as it invites users onto shared networks. Nothing in this section is a judgment about the people involved; it is a reading of the results produced, their history and how they came to be, which in the regrettable lack of any human authorship is the only thing that can be expected to be held to account.

+
+
+

Dating

+

This examination reflects the publicly available material as of September 2026; the repository in question continued to receive commits at the time of writing, so readers should treat citations to commits and files as point-in-time evidence. A forensics snapshot is publicly available on GitHub.

+
+
+
+ +
+
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/manual/distributed.html b/docs/manual/distributed.html index 9013fc72..7b5a77cd 100644 --- a/docs/manual/distributed.html +++ b/docs/manual/distributed.html @@ -7,7 +7,7 @@ - Distributed Development - Reticulum Network Stack 1.5.1 documentation + Distributed Development - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
@@ -204,7 +204,7 @@
- Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation
- + diff --git a/docs/manual/examples.html b/docs/manual/examples.html index 582a469d..82f25c9d 100644 --- a/docs/manual/examples.html +++ b/docs/manual/examples.html @@ -7,7 +7,7 @@ - Code Examples - Reticulum Network Stack 1.5.1 documentation + Code Examples - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
@@ -204,7 +204,7 @@
- Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
  • - + diff --git a/docs/manual/forhumans.html b/docs/manual/forhumans.html index bafc0839..fe05cea3 100644 --- a/docs/manual/forhumans.html +++ b/docs/manual/forhumans.html @@ -7,7 +7,7 @@ - An Explanation of Reticulum for Human Beings - Reticulum Network Stack 1.5.1 documentation + An Explanation of Reticulum for Human Beings - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
  • - + diff --git a/docs/manual/genindex.html b/docs/manual/genindex.html index afba883d..460d9066 100644 --- a/docs/manual/genindex.html +++ b/docs/manual/genindex.html @@ -5,7 +5,7 @@ - Index - Reticulum Network Stack 1.5.1 documentation + Index - Reticulum Network Stack 1.5.5 documentation @@ -178,7 +178,7 @@
    @@ -202,7 +202,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -225,6 +225,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
  • - + diff --git a/docs/manual/gettingstartedfast.html b/docs/manual/gettingstartedfast.html index 204c8596..9e92c660 100644 --- a/docs/manual/gettingstartedfast.html +++ b/docs/manual/gettingstartedfast.html @@ -7,7 +7,7 @@ - Getting Started Fast - Reticulum Network Stack 1.5.1 documentation + Getting Started Fast - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
  • - + diff --git a/docs/manual/git.html b/docs/manual/git.html index 3bff4352..f41d7a76 100644 --- a/docs/manual/git.html +++ b/docs/manual/git.html @@ -7,7 +7,7 @@ - Git Over Reticulum - Reticulum Network Stack 1.5.1 documentation + Git Over Reticulum - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
    • API Reference
    • @@ -266,6 +267,7 @@

      Git Over Reticulum

      This chapter of the manual serves as the technical reference for the distributed software development and project collaboration tools included in RNS. For a conceptual overview, see the Distributed Development chapter.

      A set of utilities for distributed collaborative software development and publishing are included in RNS.

      +_images/rngit.webp

      The system consists of two parts: The rngit node that hosts repositories, and the git-remote-rns helper that enables Git to communicate with rngit nodes. As soon as you have RNS installed on your system, you can transparently use Git with Reticulum-hosted repositories just like any other type of remote. Git over Reticulum uses URLs in the following format: rns://DESTINATION_HASH/group/repo.

      If you set a branch to track a Reticulum remote as the default upstream, you can simply use git as you normally would; all commands work transparently and as expected.

      @@ -356,6 +358,10 @@ Repository public/myrepo created

    This creates a bare Git repository at the specified path. You must have create permission for the target group. When a repository is created, the creator automatically receives adm (admin) permissions on the repository through an auto-generated .allowed file.

    +
    +

    Tip

    +

    If you want to use a different primary branch name than master, you can change it inside the bare git repository directory with git symbolic-ref HEAD refs/heads/name_of_other_branch.

    +

    All Command-Line Options (rngit create)

    usage: rngit create [-h] [--config CONFIG] [--rnsconfig RNSCONFIG]
                         [-i PATH] [-v] [-q] [--version]
    @@ -816,6 +822,7 @@ def hello_world():
     
  • commit.mu - Individual commit detail page

  • refs.mu - Branches and tags listing

  • stats.mu - Statistics page

  • +
  • no_ident.mu - Displayed to non-identified initiators if blocked

  • Templates can include the following variables:

      @@ -1594,7 +1601,7 @@ done
    -
    + diff --git a/docs/manual/hardware.html b/docs/manual/hardware.html index 72046d69..18f03933 100644 --- a/docs/manual/hardware.html +++ b/docs/manual/hardware.html @@ -7,7 +7,7 @@ - Communications Hardware - Reticulum Network Stack 1.5.1 documentation + Communications Hardware - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
    • API Reference
    • @@ -676,7 +677,7 @@ can be used with Reticulum. This includes virtual software modems such as
    - + diff --git a/docs/manual/index.html b/docs/manual/index.html index aa706ad0..f648ff43 100644 --- a/docs/manual/index.html +++ b/docs/manual/index.html @@ -7,7 +7,7 @@ - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
    • API Reference
    • @@ -372,28 +373,49 @@ to participate in the development of Reticulum itself.

  • Programs Using Reticulum
  • @@ -721,7 +830,7 @@ to participate in the development of Reticulum itself.

    - + diff --git a/docs/manual/interfaces.html b/docs/manual/interfaces.html index 2ff7a1e2..329437d8 100644 --- a/docs/manual/interfaces.html +++ b/docs/manual/interfaces.html @@ -7,7 +7,7 @@ - Configuring Interfaces - Reticulum Network Stack 1.5.1 documentation + Configuring Interfaces - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
  • - + diff --git a/docs/manual/license.html b/docs/manual/license.html index e6ea525d..4250bdc6 100644 --- a/docs/manual/license.html +++ b/docs/manual/license.html @@ -3,11 +3,11 @@ - + - Reticulum License - Reticulum Network Stack 1.5.1 documentation + Reticulum License - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
  • + diff --git a/docs/manual/networks.html b/docs/manual/networks.html index c4c25754..f2adbfcd 100644 --- a/docs/manual/networks.html +++ b/docs/manual/networks.html @@ -7,7 +7,7 @@ - Building Networks - Reticulum Network Stack 1.5.1 documentation + Building Networks - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
    • API Reference
    • @@ -664,7 +665,7 @@ differently than a mobile device roaming between radio cells.

    - + diff --git a/docs/manual/objects.inv b/docs/manual/objects.inv index bca1f245..ed2b71d9 100644 Binary files a/docs/manual/objects.inv and b/docs/manual/objects.inv differ diff --git a/docs/manual/reference.html b/docs/manual/reference.html index 887fde07..2c0c93fe 100644 --- a/docs/manual/reference.html +++ b/docs/manual/reference.html @@ -3,11 +3,11 @@ - + - API Reference - Reticulum Network Stack 1.5.1 documentation + API Reference - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
    • API Reference
    • @@ -1502,7 +1503,7 @@ statistics, you will be able to retrieve stats such as RSSI, SNRget_expected_rate()
      Returns:
      -

      The packet expected in-flight data rate of an established link.

      +

      The expected in-flight data rate of an established link.

      @@ -2340,14 +2341,14 @@ will announce it.

      -
    + diff --git a/docs/manual/search.html b/docs/manual/search.html index c4eb0cbe..5284cfa1 100644 --- a/docs/manual/search.html +++ b/docs/manual/search.html @@ -8,7 +8,7 @@ -Search - Reticulum Network Stack 1.5.1 documentation +Search - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
  • - + diff --git a/docs/manual/searchindex.js b/docs/manual/searchindex.js index 0fcc876b..cd5ed683 100644 --- a/docs/manual/searchindex.js +++ b/docs/manual/searchindex.js @@ -1 +1 @@ -Search.setIndex({"alltitles":{"A Carrier-Grade Fallacy":[[16,"a-carrier-grade-fallacy"]],"API Reference":[[10,null]],"ARM64":[[3,"arm64"]],"AX.25 KISS Interface":[[7,"ax-25-kiss-interface"]],"Accessing Repository Pages":[[4,"accessing-repository-pages"]],"Adding Radio Interfaces":[[3,"adding-radio-interfaces"]],"An Explanation of Reticulum for Human Beings":[[2,null]],"Anchor In The Flow":[[16,"anchor-in-the-flow"]],"Android":[[3,"android"]],"Announce":[[1,"announce"]],"Announce Propagation Rules":[[13,"announce-propagation-rules"]],"Announce Rate Control":[[7,"announce-rate-control"]],"Announcing Presence":[[16,"announcing-presence"]],"Artifact-Centered Workflows":[[0,"artifact-centered-workflows"]],"Author Identity Binding":[[4,"author-identity-binding"]],"Auto Interface":[[7,"auto-interface"]],"Automated Blocking":[[7,"automated-blocking"]],"Automated List Sourcing":[[14,"automated-list-sourcing"]],"Automatic Mirror Synchronization":[[4,"automatic-mirror-synchronization"]],"Backbone Interface":[[7,"backbone-interface"]],"Blackhole Management":[[14,"blackhole-management"]],"Bootstrapping Connectivity":[[3,"bootstrapping-connectivity"]],"Broadcast":[[1,"broadcast"]],"Buffer":[[1,"buffer"]],"Build Personal Infrastructure":[[3,"build-personal-infrastructure"]],"Building Networks":[[9,null]],"Channel":[[1,"channel"]],"Code Examples":[[1,null]],"Combining Hardware Types":[[5,"combining-hardware-types"]],"Command-Line Interaction":[[4,"command-line-interaction"]],"Commit Signing":[[4,"commit-signing"]],"Common Interface Options":[[7,"common-interface-options"]],"Communications Hardware":[[5,null]],"Composable Primitives":[[0,"composable-primitives"]],"Concepts & Overview":[[9,"concepts-overview"]],"Conceptual Overview":[[13,"conceptual-overview"]],"Configuration":[[4,"configuration"],[4,"id1"]],"Configuration & Data":[[14,"configuration-data"]],"Configuration Example":[[4,"configuration-example"]],"Configuration Methods":[[4,"configuration-methods"]],"Configuring Interfaces":[[7,null]],"Connect to the Distributed Backbone":[[3,"connect-to-the-distributed-backbone"]],"Connecting Remotes":[[7,"connecting-remotes"]],"Connecting Reticulum Instances Over the Internet":[[3,"connecting-reticulum-instances-over-the-internet"]],"Contributing to the Global Ret":[[3,"contributing-to-the-global-ret"]],"Cost Of A Byte":[[16,"cost-of-a-byte"]],"Creating Empty Repositories":[[4,"creating-empty-repositories"]],"Creating RNodes":[[5,"creating-rnodes"]],"Creating Signed Releases":[[4,"creating-signed-releases"]],"Creating a Network With Reticulum":[[3,"creating-a-network-with-reticulum"]],"Creating and Using Custom Interfaces":[[3,"creating-and-using-custom-interfaces"]],"Creating and Using a Network Identity":[[13,"creating-and-using-a-network-identity"]],"Creator Permissions":[[4,"creator-permissions"]],"Cryptographic Attribution":[[4,"cryptographic-attribution"]],"Cryptographic Primitives":[[13,"cryptographic-primitives"]],"Current Status":[[15,"current-status"]],"Current Usage":[[13,"current-usage"]],"Custom Interfaces":[[1,"custom-interfaces"],[7,"custom-interfaces"]],"Customizing Templates":[[4,"customizing-templates"]],"Death To The Address":[[16,"death-to-the-address"]],"Debian Bookworm":[[3,"debian-bookworm"]],"Decentralization Or Uncentralizability?":[[16,"decentralization-or-uncentralizability"]],"Design Patterns For Post-IP Systems":[[16,"design-patterns-for-post-ip-systems"]],"Destination Naming":[[13,"destination-naming"]],"Destinations":[[13,"destinations"]],"Destinations, Not Addresses":[[9,"destinations-not-addresses"]],"Develop a Program with Reticulum":[[3,"develop-a-program-with-reticulum"]],"Discoverable Interfaces":[[7,"discoverable-interfaces"]],"Discovering Interfaces":[[14,"discovering-interfaces"]],"Discovery Parameters":[[7,"discovery-parameters"]],"Distributed Development":[[0,null]],"Distribution Without Intermediaries":[[0,"distribution-without-intermediaries"]],"Donations":[[12,"donations"]],"Echo":[[1,"echo"]],"Emergent Patterns":[[16,"emergent-patterns"]],"Enabling Discovery":[[7,"enabling-discovery"]],"Enabling the Git Page Node":[[4,"enabling-the-git-page-node"]],"Encryption Is Not A Feature":[[16,"encryption-is-not-a-feature"]],"Ethernet-based Hardware":[[5,"ethernet-based-hardware"]],"Ethics Of The Tool":[[16,"ethics-of-the-tool"]],"Example Configuration":[[7,"example-configuration"]],"Fabric Of The Independent":[[16,"fabric-of-the-independent"]],"Fallacy Of The Cloud":[[16,"fallacy-of-the-cloud"]],"Filetransfer":[[1,"filetransfer"]],"Finding Your Way":[[3,"finding-your-way"]],"Fixed Serial Port Names":[[14,"fixed-serial-port-names"]],"Flow & Time":[[16,"flow-time"]],"Forking Repositories":[[4,"forking-repositories"]],"Formatting & Syntax Highlighting":[[4,"formatting-syntax-highlighting"]],"Future Implications":[[13,"future-implications"]],"Getting Further":[[13,"getting-further"]],"Getting Started Fast":[[3,null]],"Git Configuration Parameters":[[4,"git-configuration-parameters"]],"Git Over Reticulum":[[4,null]],"Goals":[[13,"goals"]],"Heltec LoRa32 v2.0":[[5,"heltec-lora32-v2-0"]],"Heltec LoRa32 v3.0":[[5,"heltec-lora32-v3-0"]],"Heltec LoRa32 v4.0":[[5,"heltec-lora32-v4-0"]],"Heltec T114":[[5,"heltec-t114"]],"Heterogeneous Connectivity":[[9,"heterogeneous-connectivity"]],"Hostile Environments":[[16,"hostile-environments"]],"Hosting Public Entrypoints":[[3,"hosting-public-entrypoints"]],"I2P Interface":[[7,"i2p-interface"]],"Identification":[[1,"example-identify"]],"Identities":[[13,"understanding-identities"]],"Identity & Destination Aliases":[[4,"identity-destination-aliases"]],"Identity and Nomadism":[[16,"identity-and-nomadism"]],"Improving System Configuration":[[14,"improving-system-configuration"]],"Included Utility Programs":[[14,"included-utility-programs"]],"Indices and Tables":[[6,"indices-and-tables"]],"Installation":[[5,"installation"]],"Interface Access Codes":[[13,"interface-access-codes"]],"Interface Modes":[[7,"interface-modes"],[7,"interfaces-modes"]],"Interface Modules & Connectivity Resources":[[11,"interface-modules-connectivity-resources"]],"Interface Types and Devices":[[15,"interface-types-and-devices"]],"Introduction & Basic Functionality":[[13,"introduction-basic-functionality"]],"Introductory Considerations":[[9,"introductory-considerations"]],"KISS Interface":[[7,"kiss-interface"]],"LXMF":[[11,"lxmf"]],"LXMF Interactive Client":[[11,"lxmf-interactive-client"]],"LXMFy":[[11,"lxmfy"]],"LXST":[[11,"id16"]],"LXST Phone":[[11,"lxst-phone"]],"Liberation From Limits":[[16,"liberation-from-limits"]],"LilyGO LoRa32 v1.0":[[5,"lilygo-lora32-v1-0"]],"LilyGO LoRa32 v2.0":[[5,"lilygo-lora32-v2-0"]],"LilyGO LoRa32 v2.1":[[5,"lilygo-lora32-v2-1"]],"LilyGO T-Beam":[[5,"lilygo-t-beam"]],"LilyGO T-Beam Supreme":[[5,"lilygo-t-beam-supreme"]],"LilyGO T-Deck":[[5,"lilygo-t-deck"]],"LilyGO T-Echo":[[5,"lilygo-t-echo"]],"LilyGO T3S3":[[5,"lilygo-t3s3"]],"Link":[[1,"link"]],"Link Establishment in Detail":[[13,"link-establishment-in-detail"]],"Listeners":[[7,"listeners"]],"Local Blackhole Management":[[14,"local-blackhole-management"]],"Long Archive":[[0,"long-archive"]],"MacOS":[[3,"macos"]],"Managing Group Permissions":[[4,"managing-group-permissions"]],"Managing Repository Permissions":[[4,"managing-repository-permissions"]],"Managing Work Document Permissions":[[4,"managing-work-document-permissions"]],"Manual Synchronization":[[4,"manual-synchronization"]],"Merits Of Scarcity":[[16,"merits-of-scarcity"]],"MeshChatX":[[11,"meshchatx"]],"Micron Parser JS":[[11,"micron-parser-js"]],"Minimal":[[1,"minimal"]],"Mirroring Repositories":[[4,"mirroring-repositories"]],"Mixing Strategies":[[3,"mixing-strategies"]],"Motivation":[[13,"motivation"]],"Naming Is Power":[[16,"naming-is-power"]],"Network Health & Responsibility":[[3,"network-health-responsibility"]],"Network Identities":[[13,"network-identities"]],"New Destination Rate Limiting":[[7,"new-destination-rate-limiting"]],"Node Types":[[13,"node-types"]],"Nomad Network":[[11,"nomad-network"]],"Obtaining Verified Releases":[[4,"obtaining-verified-releases"]],"Offline Verification":[[4,"offline-verification"]],"Open Sky":[[16,"open-sky"]],"OpenCom XL":[[5,"opencom-xl"]],"OpenWRT":[[3,"openwrt"]],"Packet Prioritisation":[[13,"packet-prioritisation"]],"Packet Radio Modems":[[5,"packet-radio-modems"]],"Path Request Burst Control":[[7,"path-request-burst-control"]],"Permission Configuration Locations":[[4,"permission-configuration-locations"]],"Permission Examples":[[4,"permission-examples"]],"Permission Hierarchy":[[4,"permission-hierarchy"]],"Permission Short Forms":[[4,"permission-short-forms"]],"Permission Types":[[4,"permission-types"]],"Permission Validation":[[4,"permission-validation"]],"Permissions":[[4,"permissions"]],"Personal Infrastructure":[[16,"personal-infrastructure"]],"Physics Of Trust":[[16,"physics-of-trust"]],"Pipe Interface":[[7,"pipe-interface"]],"Platform-Specific Install Notes":[[3,"platform-specific-install-notes"]],"Portable Existence":[[16,"portable-existence"]],"Prerequisites":[[4,"prerequisites"]],"Preserving Human Agency":[[16,"preserving-human-agency"]],"Programs & Utilities":[[11,"programs-utilities"]],"Programs Using Reticulum":[[11,null]],"Proposing Work Documents":[[4,"proposing-work-documents"]],"Protocol Specifics":[[13,"protocol-specifics"]],"Protocols":[[11,"protocols"]],"Protocols Over Platforms":[[0,"protocols-over-platforms"]],"Provide Feedback":[[12,"provide-feedback"]],"Public Domain Protocol":[[16,"public-domain-protocol"]],"Public Key Announcements":[[13,"public-key-announcements"]],"Publishing Blackhole Lists":[[14,"publishing-blackhole-lists"]],"Pure-Python Reticulum":[[3,"pure-python-reticulum"]],"RAK4631-based Boards":[[5,"rak4631-based-boards"]],"RBrowser":[[11,"rbrowser"]],"RISC-V":[[3,"risc-v"]],"RNMon":[[11,"rnmon"]],"RNS FileSync":[[11,"rns-filesync"]],"RNS Page Node":[[11,"rns-page-node"]],"RNode":[[5,"rnode"]],"RNode LoRa Interface":[[7,"rnode-lora-interface"]],"RNode Multi Interface":[[7,"rnode-multi-interface"]],"RRC":[[11,"rrc"]],"Raspberry Pi":[[3,"raspberry-pi"]],"Reaching the Destination":[[13,"reaching-the-destination"]],"Reference Implementation":[[15,"reference-implementation"]],"Reference Setup":[[13,"reference-setup"]],"Release Management":[[4,"release-management"]],"Release Storage & Structure":[[4,"release-storage-structure"]],"Remote Management":[[14,"remote-management"]],"Remote Permission Management":[[4,"remote-permission-management"]],"Remote Shell":[[11,"remote-shell"]],"Repository Creation & Management":[[4,"repository-creation-management"]],"Repository Statistics":[[4,"repository-statistics"]],"Repository Structure":[[4,"repository-structure"]],"Requests & Responses":[[1,"requests-responses"]],"Resolving Dependency & Installation Issues":[[3,"resolving-dependency-installation-issues"]],"Resources":[[13,"resources"]],"Restoration":[[0,"restoration"]],"RetiBBS":[[11,"retibbs"]],"Reticulum License":[[8,null]],"Reticulum Network Stack Manual":[[6,null]],"Reticulum Network Telephone":[[11,"reticulum-network-telephone"]],"Reticulum Relay Chat":[[11,"reticulum-relay-chat"]],"Reticulum Transport":[[13,"reticulum-transport"]],"Reticulum as a System Service":[[14,"reticulum-as-a-system-service"]],"Retipedia":[[11,"retipedia"]],"Roaming Nodes":[[16,"roaming-nodes"]],"Security Considerations":[[7,"security-considerations"]],"Serial Interface":[[7,"serial-interface"]],"Serial Lines & Devices":[[5,"serial-lines-devices"]],"Serving Pages Over Nomad Network":[[4,"serving-pages-over-nomad-network"]],"Sideband":[[11,"sideband"]],"Signing Commits":[[4,"signing-commits"]],"Sovereignty Through Infrastructure":[[0,"sovereignty-through-infrastructure"],[16,"sovereignty-through-infrastructure"]],"Standalone Reticulum Installation":[[3,"standalone-reticulum-installation"]],"Start Of The Road":[[0,"start-of-the-road"]],"State Management":[[4,"state-management"]],"Store & Forward":[[16,"store-forward"]],"Support Reticulum":[[12,null]],"Supported Boards and Devices":[[5,"supported-boards-and-devices"]],"Systemwide Service":[[14,"systemwide-service"]],"TCP Client Interface":[[7,"tcp-client-interface"]],"TCP Server Interface":[[7,"tcp-server-interface"]],"Table Of Contents":[[6,"table-of-contents"]],"The Ability To Disconnect":[[16,"the-ability-to-disconnect"]],"The Announce Mechanism in Detail":[[13,"the-announce-mechanism-in-detail"]],"The Bandwidth Fallacy":[[16,"the-bandwidth-fallacy"]],"The Harm Principle":[[16,"the-harm-principle"]],"The Illusion Of The Center":[[16,"the-illusion-of-the-center"]],"The Interface Is The Medium":[[16,"the-interface-is-the-medium"]],"The Original Architecture":[[0,"the-original-architecture"]],"The Platform Interregnum":[[0,"the-platform-interregnum"]],"The Release Workflow":[[4,"the-release-workflow"]],"The Work Is Finished":[[16,"the-work-is-finished"]],"The rncp Utility":[[14,"the-rncp-utility"]],"The rngit Utility":[[4,"the-rngit-utility"],[14,"the-rngit-utility"]],"The rnid Utility":[[14,"the-rnid-utility"]],"The rnodeconf Utility":[[14,"the-rnodeconf-utility"]],"The rnpath Utility":[[14,"the-rnpath-utility"]],"The rnprobe Utility":[[14,"the-rnprobe-utility"]],"The rnsd Utility":[[14,"the-rnsd-utility"]],"The rnsh Utility":[[14,"the-rnsh-utility"]],"The rnstatus Utility":[[14,"the-rnstatus-utility"]],"The rnx Utility":[[14,"the-rnx-utility"]],"Transport Nodes and Instances":[[9,"transport-nodes-and-instances"]],"Trustless Networking":[[9,"trustless-networking"]],"Try Using a Reticulum-based Program":[[3,"try-using-a-reticulum-based-program"]],"Tuning Ingress Queues":[[7,"tuning-ingress-queues"]],"UDP Interface":[[7,"udp-interface"]],"Ubuntu Lunar":[[3,"ubuntu-lunar"]],"Understanding Reticulum":[[13,null]],"Unsigned RNode v2.x":[[5,"unsigned-rnode-v2-x"]],"Usage with Reticulum":[[5,"usage-with-reticulum"]],"Userspace Service":[[14,"userspace-service"]],"Using Reticulum on Your System":[[14,null]],"Using the Included Utilities":[[3,"using-the-included-utilities"]],"Validating Commit Signatures":[[4,"validating-commit-signatures"]],"Verified Releases":[[4,"verified-releases"]],"What does Reticulum Offer?":[[15,"what-does-reticulum-offer"]],"What is Reticulum?":[[15,null]],"Where can Reticulum be Used?":[[15,"where-can-reticulum-be-used"]],"WiFi-based Hardware":[[5,"wifi-based-hardware"]],"Windows":[[3,"windows"]],"Wire Format":[[13,"wire-format"]],"Work Document Permissions":[[4,"work-document-permissions"]],"Work Documents":[[4,"work-documents"]],"Working With Work Documents":[[4,"working-with-work-documents"]],"Zen of Reticulum":[[16,null]],"Zero-Trust Architectures":[[16,"zero-trust-architectures"]]},"docnames":["distributed","examples","forhumans","gettingstartedfast","git","hardware","index","interfaces","license","networks","reference","software","support","understanding","using","whatis","zen"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2},"filenames":["distributed.rst","examples.rst","forhumans.rst","gettingstartedfast.rst","git.rst","hardware.rst","index.rst","interfaces.rst","license.rst","networks.rst","reference.rst","software.rst","support.rst","understanding.rst","using.rst","whatis.rst","zen.rst"],"indexentries":{"__init__() (rns.rawchannelreader method)":[[10,"RNS.RawChannelReader.__init__",false]],"__init__() (rns.rawchannelwriter method)":[[10,"RNS.RawChannelWriter.__init__",false]],"accepts_links() (rns.destination method)":[[10,"RNS.Destination.accepts_links",false]],"add_message_handler() (rns.channel.channel method)":[[10,"RNS.Channel.Channel.add_message_handler",false]],"add_ready_callback() (rns.rawchannelreader method)":[[10,"RNS.RawChannelReader.add_ready_callback",false]],"advertise() (rns.resource method)":[[10,"RNS.Resource.advertise",false]],"announce() (rns.destination method)":[[10,"RNS.Destination.announce",false]],"announce_cap (rns.reticulum attribute)":[[10,"RNS.Reticulum.ANNOUNCE_CAP",false]],"app_and_aspects_from_name() (rns.destination static method)":[[10,"RNS.Destination.app_and_aspects_from_name",false]],"await_path() (rns.transport static method)":[[10,"RNS.Transport.await_path",false]],"blackhole_identity() (rns.transport static method)":[[10,"RNS.Transport.blackhole_identity",false]],"blackhole_sources() (rns.reticulum static method)":[[10,"RNS.Reticulum.blackhole_sources",false]],"buffer (class in rns)":[[10,"RNS.Buffer",false]],"cancel() (rns.resource method)":[[10,"RNS.Resource.cancel",false]],"channel (class in rns.channel)":[[10,"RNS.Channel.Channel",false]],"clear_default_app_data() (rns.destination method)":[[10,"RNS.Destination.clear_default_app_data",false]],"concluded() (rns.requestreceipt method)":[[10,"RNS.RequestReceipt.concluded",false]],"create_bidirectional_buffer() (rns.buffer static method)":[[10,"RNS.Buffer.create_bidirectional_buffer",false]],"create_keys() (rns.destination method)":[[10,"RNS.Destination.create_keys",false]],"create_reader() (rns.buffer static method)":[[10,"RNS.Buffer.create_reader",false]],"create_writer() (rns.buffer static method)":[[10,"RNS.Buffer.create_writer",false]],"current_ratchet_id() (rns.identity static method)":[[10,"RNS.Identity.current_ratchet_id",false]],"curve (rns.identity attribute)":[[10,"RNS.Identity.CURVE",false]],"curve (rns.link attribute)":[[10,"RNS.Link.CURVE",false]],"decrypt() (rns.destination method)":[[10,"RNS.Destination.decrypt",false]],"decrypt() (rns.identity method)":[[10,"RNS.Identity.decrypt",false]],"default_per_hop_timeout (rns.reticulum attribute)":[[10,"RNS.Reticulum.DEFAULT_PER_HOP_TIMEOUT",false]],"deregister_announce_handler() (rns.transport static method)":[[10,"RNS.Transport.deregister_announce_handler",false]],"deregister_request_handler() (rns.destination method)":[[10,"RNS.Destination.deregister_request_handler",false]],"destination (class in rns)":[[10,"RNS.Destination",false]],"discovered_interfaces() (rns.reticulum static method)":[[10,"RNS.Reticulum.discovered_interfaces",false]],"enable_ratchets() (rns.destination method)":[[10,"RNS.Destination.enable_ratchets",false]],"encrypt() (rns.destination method)":[[10,"RNS.Destination.encrypt",false]],"encrypt() (rns.identity method)":[[10,"RNS.Identity.encrypt",false]],"encrypted_mdu (rns.packet attribute)":[[10,"RNS.Packet.ENCRYPTED_MDU",false]],"enforce_ratchets() (rns.destination method)":[[10,"RNS.Destination.enforce_ratchets",false]],"establishment_timeout_per_hop (rns.link attribute)":[[10,"RNS.Link.ESTABLISHMENT_TIMEOUT_PER_HOP",false]],"expand_name() (rns.destination static method)":[[10,"RNS.Destination.expand_name",false]],"from_bytes() (rns.identity static method)":[[10,"RNS.Identity.from_bytes",false]],"from_file() (rns.identity static method)":[[10,"RNS.Identity.from_file",false]],"full_hash() (rns.identity static method)":[[10,"RNS.Identity.full_hash",false]],"get_age() (rns.link method)":[[10,"RNS.Link.get_age",false]],"get_channel() (rns.link method)":[[10,"RNS.Link.get_channel",false]],"get_data_size() (rns.resource method)":[[10,"RNS.Resource.get_data_size",false]],"get_establishment_rate() (rns.link method)":[[10,"RNS.Link.get_establishment_rate",false]],"get_expected_rate() (rns.link method)":[[10,"RNS.Link.get_expected_rate",false]],"get_first_hop_timeout() (rns.reticulum method)":[[10,"RNS.Reticulum.get_first_hop_timeout",false]],"get_hash() (rns.resource method)":[[10,"RNS.Resource.get_hash",false]],"get_instance() (rns.reticulum static method)":[[10,"RNS.Reticulum.get_instance",false]],"get_lowest_interface_bitrate() (rns.reticulum method)":[[10,"RNS.Reticulum.get_lowest_interface_bitrate",false]],"get_mdu() (rns.link method)":[[10,"RNS.Link.get_mdu",false]],"get_medium_path_timeout() (rns.reticulum method)":[[10,"RNS.Reticulum.get_medium_path_timeout",false]],"get_mode() (rns.link method)":[[10,"RNS.Link.get_mode",false]],"get_mtu() (rns.link method)":[[10,"RNS.Link.get_mtu",false]],"get_parts() (rns.resource method)":[[10,"RNS.Resource.get_parts",false]],"get_private_key() (rns.destination method)":[[10,"RNS.Destination.get_private_key",false]],"get_private_key() (rns.identity method)":[[10,"RNS.Identity.get_private_key",false]],"get_progress() (rns.requestreceipt method)":[[10,"RNS.RequestReceipt.get_progress",false]],"get_progress() (rns.resource method)":[[10,"RNS.Resource.get_progress",false]],"get_public_key() (rns.identity method)":[[10,"RNS.Identity.get_public_key",false]],"get_q() (rns.link method)":[[10,"RNS.Link.get_q",false]],"get_q() (rns.packet method)":[[10,"RNS.Packet.get_q",false]],"get_random_hash() (rns.identity static method)":[[10,"RNS.Identity.get_random_hash",false]],"get_remote_identity() (rns.link method)":[[10,"RNS.Link.get_remote_identity",false]],"get_request_id() (rns.requestreceipt method)":[[10,"RNS.RequestReceipt.get_request_id",false]],"get_response() (rns.requestreceipt method)":[[10,"RNS.RequestReceipt.get_response",false]],"get_response_time() (rns.requestreceipt method)":[[10,"RNS.RequestReceipt.get_response_time",false]],"get_rssi() (rns.link method)":[[10,"RNS.Link.get_rssi",false]],"get_rssi() (rns.packet method)":[[10,"RNS.Packet.get_rssi",false]],"get_rtt() (rns.packetreceipt method)":[[10,"RNS.PacketReceipt.get_rtt",false]],"get_segments() (rns.resource method)":[[10,"RNS.Resource.get_segments",false]],"get_snr() (rns.link method)":[[10,"RNS.Link.get_snr",false]],"get_snr() (rns.packet method)":[[10,"RNS.Packet.get_snr",false]],"get_status() (rns.packetreceipt method)":[[10,"RNS.PacketReceipt.get_status",false]],"get_status() (rns.requestreceipt method)":[[10,"RNS.RequestReceipt.get_status",false]],"get_transfer_size() (rns.resource method)":[[10,"RNS.Resource.get_transfer_size",false]],"has_path() (rns.transport static method)":[[10,"RNS.Transport.has_path",false]],"hash() (rns.destination static method)":[[10,"RNS.Destination.hash",false]],"hash_from_name_and_identity() (rns.destination static method)":[[10,"RNS.Destination.hash_from_name_and_identity",false]],"hops_to() (rns.transport static method)":[[10,"RNS.Transport.hops_to",false]],"identify() (rns.link method)":[[10,"RNS.Link.identify",false]],"identity (class in rns)":[[10,"RNS.Identity",false]],"inactive_for() (rns.link method)":[[10,"RNS.Link.inactive_for",false]],"interface_discovery_sources() (rns.reticulum static method)":[[10,"RNS.Reticulum.interface_discovery_sources",false]],"is_compressed() (rns.resource method)":[[10,"RNS.Resource.is_compressed",false]],"is_ready_to_send() (rns.channel.channel method)":[[10,"RNS.Channel.Channel.is_ready_to_send",false]],"keepalive (rns.link attribute)":[[10,"RNS.Link.KEEPALIVE",false]],"keepalive_timeout_factor (rns.link attribute)":[[10,"RNS.Link.KEEPALIVE_TIMEOUT_FACTOR",false]],"keysize (rns.identity attribute)":[[10,"RNS.Identity.KEYSIZE",false]],"link (class in rns)":[[10,"RNS.Link",false]],"link_mtu_discovery (rns.reticulum attribute)":[[10,"RNS.Reticulum.LINK_MTU_DISCOVERY",false]],"link_mtu_discovery() (rns.reticulum static method)":[[10,"RNS.Reticulum.link_mtu_discovery",false]],"load_private_key() (rns.destination method)":[[10,"RNS.Destination.load_private_key",false]],"load_private_key() (rns.identity method)":[[10,"RNS.Identity.load_private_key",false]],"load_public_key() (rns.identity method)":[[10,"RNS.Identity.load_public_key",false]],"mdu (rns.channel.channel property)":[[10,"RNS.Channel.Channel.mdu",false]],"messagebase (class in rns)":[[10,"RNS.MessageBase",false]],"minimum_bitrate (rns.reticulum attribute)":[[10,"RNS.Reticulum.MINIMUM_BITRATE",false]],"msgtype (rns.messagebase attribute)":[[10,"RNS.MessageBase.MSGTYPE",false]],"mtu (rns.reticulum attribute)":[[10,"RNS.Reticulum.MTU",false]],"next_hop() (rns.transport static method)":[[10,"RNS.Transport.next_hop",false]],"next_hop_interface() (rns.transport static method)":[[10,"RNS.Transport.next_hop_interface",false]],"no_data_for() (rns.link method)":[[10,"RNS.Link.no_data_for",false]],"no_inbound_for() (rns.link method)":[[10,"RNS.Link.no_inbound_for",false]],"no_outbound_for() (rns.link method)":[[10,"RNS.Link.no_outbound_for",false]],"pack() (rns.messagebase method)":[[10,"RNS.MessageBase.pack",false]],"packet (class in rns)":[[10,"RNS.Packet",false]],"packetreceipt (class in rns)":[[10,"RNS.PacketReceipt",false]],"pathfinder_m (rns.transport attribute)":[[10,"RNS.Transport.PATHFINDER_M",false]],"plain_mdu (rns.packet attribute)":[[10,"RNS.Packet.PLAIN_MDU",false]],"pub_to_file() (rns.identity method)":[[10,"RNS.Identity.pub_to_file",false]],"publish_blackhole_enabled() (rns.reticulum static method)":[[10,"RNS.Reticulum.publish_blackhole_enabled",false]],"ratchet_count (rns.destination attribute)":[[10,"RNS.Destination.RATCHET_COUNT",false]],"ratchet_expiry (rns.identity attribute)":[[10,"RNS.Identity.RATCHET_EXPIRY",false]],"ratchet_interval (rns.destination attribute)":[[10,"RNS.Destination.RATCHET_INTERVAL",false]],"ratchetsize (rns.identity attribute)":[[10,"RNS.Identity.RATCHETSIZE",false]],"rawchannelreader (class in rns)":[[10,"RNS.RawChannelReader",false]],"rawchannelwriter (class in rns)":[[10,"RNS.RawChannelWriter",false]],"recall() (rns.identity static method)":[[10,"RNS.Identity.recall",false]],"recall_app_data() (rns.identity static method)":[[10,"RNS.Identity.recall_app_data",false]],"register_announce_handler() (rns.transport static method)":[[10,"RNS.Transport.register_announce_handler",false]],"register_message_type() (rns.channel.channel method)":[[10,"RNS.Channel.Channel.register_message_type",false]],"register_request_handler() (rns.destination method)":[[10,"RNS.Destination.register_request_handler",false]],"remote_management_enabled() (rns.reticulum static method)":[[10,"RNS.Reticulum.remote_management_enabled",false]],"remove_message_handler() (rns.channel.channel method)":[[10,"RNS.Channel.Channel.remove_message_handler",false]],"remove_ready_callback() (rns.rawchannelreader method)":[[10,"RNS.RawChannelReader.remove_ready_callback",false]],"request() (rns.link method)":[[10,"RNS.Link.request",false]],"request_path() (rns.transport static method)":[[10,"RNS.Transport.request_path",false]],"requestreceipt (class in rns)":[[10,"RNS.RequestReceipt",false]],"required_discovery_value() (rns.reticulum static method)":[[10,"RNS.Reticulum.required_discovery_value",false]],"resend() (rns.packet method)":[[10,"RNS.Packet.resend",false]],"resource (class in rns)":[[10,"RNS.Resource",false]],"reticulum (class in rns)":[[10,"RNS.Reticulum",false]],"send() (rns.channel.channel method)":[[10,"RNS.Channel.Channel.send",false]],"send() (rns.packet method)":[[10,"RNS.Packet.send",false]],"set_default_app_data() (rns.destination method)":[[10,"RNS.Destination.set_default_app_data",false]],"set_delivery_callback() (rns.packetreceipt method)":[[10,"RNS.PacketReceipt.set_delivery_callback",false]],"set_link_closed_callback() (rns.link method)":[[10,"RNS.Link.set_link_closed_callback",false]],"set_link_established_callback() (rns.destination method)":[[10,"RNS.Destination.set_link_established_callback",false]],"set_max_request_size() (rns.destination method)":[[10,"RNS.Destination.set_max_request_size",false]],"set_packet_callback() (rns.destination method)":[[10,"RNS.Destination.set_packet_callback",false]],"set_packet_callback() (rns.link method)":[[10,"RNS.Link.set_packet_callback",false]],"set_proof_requested_callback() (rns.destination method)":[[10,"RNS.Destination.set_proof_requested_callback",false]],"set_proof_strategy() (rns.destination method)":[[10,"RNS.Destination.set_proof_strategy",false]],"set_ratchet_interval() (rns.destination method)":[[10,"RNS.Destination.set_ratchet_interval",false]],"set_remote_identified_callback() (rns.link method)":[[10,"RNS.Link.set_remote_identified_callback",false]],"set_resource_callback() (rns.link method)":[[10,"RNS.Link.set_resource_callback",false]],"set_resource_concluded_callback() (rns.link method)":[[10,"RNS.Link.set_resource_concluded_callback",false]],"set_resource_started_callback() (rns.link method)":[[10,"RNS.Link.set_resource_started_callback",false]],"set_resource_strategy() (rns.link method)":[[10,"RNS.Link.set_resource_strategy",false]],"set_retained_ratchets() (rns.destination method)":[[10,"RNS.Destination.set_retained_ratchets",false]],"set_timeout() (rns.packetreceipt method)":[[10,"RNS.PacketReceipt.set_timeout",false]],"set_timeout_callback() (rns.packetreceipt method)":[[10,"RNS.PacketReceipt.set_timeout_callback",false]],"should_use_implicit_proof() (rns.reticulum static method)":[[10,"RNS.Reticulum.should_use_implicit_proof",false]],"sign() (rns.destination method)":[[10,"RNS.Destination.sign",false]],"sign() (rns.identity method)":[[10,"RNS.Identity.sign",false]],"stale_grace (rns.link attribute)":[[10,"RNS.Link.STALE_GRACE",false]],"stale_time (rns.link attribute)":[[10,"RNS.Link.STALE_TIME",false]],"teardown() (rns.link method)":[[10,"RNS.Link.teardown",false]],"to_file() (rns.identity method)":[[10,"RNS.Identity.to_file",false]],"track_phy_stats() (rns.link method)":[[10,"RNS.Link.track_phy_stats",false]],"transport (class in rns)":[[10,"RNS.Transport",false]],"transport_enabled() (rns.reticulum static method)":[[10,"RNS.Reticulum.transport_enabled",false]],"truncated_hash() (rns.identity static method)":[[10,"RNS.Identity.truncated_hash",false]],"truncated_hashlength (rns.identity attribute)":[[10,"RNS.Identity.TRUNCATED_HASHLENGTH",false]],"unblackhole_identity() (rns.transport static method)":[[10,"RNS.Transport.unblackhole_identity",false]],"unpack() (rns.messagebase method)":[[10,"RNS.MessageBase.unpack",false]],"validate() (rns.identity method)":[[10,"RNS.Identity.validate",false]]},"objects":{"RNS":[[10,0,1,"","Buffer"],[10,0,1,"","Destination"],[10,0,1,"","Identity"],[10,0,1,"","Link"],[10,0,1,"","MessageBase"],[10,0,1,"","Packet"],[10,0,1,"","PacketReceipt"],[10,0,1,"","RawChannelReader"],[10,0,1,"","RawChannelWriter"],[10,0,1,"","RequestReceipt"],[10,0,1,"","Resource"],[10,0,1,"","Reticulum"],[10,0,1,"","Transport"]],"RNS.Buffer":[[10,1,1,"","create_bidirectional_buffer"],[10,1,1,"","create_reader"],[10,1,1,"","create_writer"]],"RNS.Channel":[[10,0,1,"","Channel"]],"RNS.Channel.Channel":[[10,1,1,"","add_message_handler"],[10,1,1,"","is_ready_to_send"],[10,2,1,"","mdu"],[10,1,1,"","register_message_type"],[10,1,1,"","remove_message_handler"],[10,1,1,"","send"]],"RNS.Destination":[[10,3,1,"","RATCHET_COUNT"],[10,3,1,"","RATCHET_INTERVAL"],[10,1,1,"","accepts_links"],[10,1,1,"","announce"],[10,1,1,"","app_and_aspects_from_name"],[10,1,1,"","clear_default_app_data"],[10,1,1,"","create_keys"],[10,1,1,"","decrypt"],[10,1,1,"","deregister_request_handler"],[10,1,1,"","enable_ratchets"],[10,1,1,"","encrypt"],[10,1,1,"","enforce_ratchets"],[10,1,1,"","expand_name"],[10,1,1,"","get_private_key"],[10,1,1,"","hash"],[10,1,1,"","hash_from_name_and_identity"],[10,1,1,"","load_private_key"],[10,1,1,"","register_request_handler"],[10,1,1,"","set_default_app_data"],[10,1,1,"","set_link_established_callback"],[10,1,1,"","set_max_request_size"],[10,1,1,"","set_packet_callback"],[10,1,1,"","set_proof_requested_callback"],[10,1,1,"","set_proof_strategy"],[10,1,1,"","set_ratchet_interval"],[10,1,1,"","set_retained_ratchets"],[10,1,1,"","sign"]],"RNS.Identity":[[10,3,1,"","CURVE"],[10,3,1,"","KEYSIZE"],[10,3,1,"","RATCHETSIZE"],[10,3,1,"","RATCHET_EXPIRY"],[10,3,1,"","TRUNCATED_HASHLENGTH"],[10,1,1,"","current_ratchet_id"],[10,1,1,"","decrypt"],[10,1,1,"","encrypt"],[10,1,1,"","from_bytes"],[10,1,1,"","from_file"],[10,1,1,"","full_hash"],[10,1,1,"","get_private_key"],[10,1,1,"","get_public_key"],[10,1,1,"","get_random_hash"],[10,1,1,"","load_private_key"],[10,1,1,"","load_public_key"],[10,1,1,"","pub_to_file"],[10,1,1,"","recall"],[10,1,1,"","recall_app_data"],[10,1,1,"","sign"],[10,1,1,"","to_file"],[10,1,1,"","truncated_hash"],[10,1,1,"","validate"]],"RNS.Link":[[10,3,1,"","CURVE"],[10,3,1,"","ESTABLISHMENT_TIMEOUT_PER_HOP"],[10,3,1,"","KEEPALIVE"],[10,3,1,"","KEEPALIVE_TIMEOUT_FACTOR"],[10,3,1,"","STALE_GRACE"],[10,3,1,"","STALE_TIME"],[10,1,1,"","get_age"],[10,1,1,"","get_channel"],[10,1,1,"","get_establishment_rate"],[10,1,1,"","get_expected_rate"],[10,1,1,"","get_mdu"],[10,1,1,"","get_mode"],[10,1,1,"","get_mtu"],[10,1,1,"","get_q"],[10,1,1,"","get_remote_identity"],[10,1,1,"","get_rssi"],[10,1,1,"","get_snr"],[10,1,1,"","identify"],[10,1,1,"","inactive_for"],[10,1,1,"","no_data_for"],[10,1,1,"","no_inbound_for"],[10,1,1,"","no_outbound_for"],[10,1,1,"","request"],[10,1,1,"","set_link_closed_callback"],[10,1,1,"","set_packet_callback"],[10,1,1,"","set_remote_identified_callback"],[10,1,1,"","set_resource_callback"],[10,1,1,"","set_resource_concluded_callback"],[10,1,1,"","set_resource_started_callback"],[10,1,1,"","set_resource_strategy"],[10,1,1,"","teardown"],[10,1,1,"","track_phy_stats"]],"RNS.MessageBase":[[10,3,1,"","MSGTYPE"],[10,1,1,"","pack"],[10,1,1,"","unpack"]],"RNS.Packet":[[10,3,1,"","ENCRYPTED_MDU"],[10,3,1,"","PLAIN_MDU"],[10,1,1,"","get_q"],[10,1,1,"","get_rssi"],[10,1,1,"","get_snr"],[10,1,1,"","resend"],[10,1,1,"","send"]],"RNS.PacketReceipt":[[10,1,1,"","get_rtt"],[10,1,1,"","get_status"],[10,1,1,"","set_delivery_callback"],[10,1,1,"","set_timeout"],[10,1,1,"","set_timeout_callback"]],"RNS.RawChannelReader":[[10,1,1,"","__init__"],[10,1,1,"","add_ready_callback"],[10,1,1,"","remove_ready_callback"]],"RNS.RawChannelWriter":[[10,1,1,"","__init__"]],"RNS.RequestReceipt":[[10,1,1,"","concluded"],[10,1,1,"","get_progress"],[10,1,1,"","get_request_id"],[10,1,1,"","get_response"],[10,1,1,"","get_response_time"],[10,1,1,"","get_status"]],"RNS.Resource":[[10,1,1,"","advertise"],[10,1,1,"","cancel"],[10,1,1,"","get_data_size"],[10,1,1,"","get_hash"],[10,1,1,"","get_parts"],[10,1,1,"","get_progress"],[10,1,1,"","get_segments"],[10,1,1,"","get_transfer_size"],[10,1,1,"","is_compressed"]],"RNS.Reticulum":[[10,3,1,"","ANNOUNCE_CAP"],[10,3,1,"","DEFAULT_PER_HOP_TIMEOUT"],[10,3,1,"","LINK_MTU_DISCOVERY"],[10,3,1,"","MINIMUM_BITRATE"],[10,3,1,"","MTU"],[10,1,1,"","blackhole_sources"],[10,1,1,"","discovered_interfaces"],[10,1,1,"","get_first_hop_timeout"],[10,1,1,"","get_instance"],[10,1,1,"","get_lowest_interface_bitrate"],[10,1,1,"","get_medium_path_timeout"],[10,1,1,"","interface_discovery_sources"],[10,1,1,"","link_mtu_discovery"],[10,1,1,"","publish_blackhole_enabled"],[10,1,1,"","remote_management_enabled"],[10,1,1,"","required_discovery_value"],[10,1,1,"","should_use_implicit_proof"],[10,1,1,"","transport_enabled"]],"RNS.Transport":[[10,3,1,"","PATHFINDER_M"],[10,1,1,"","await_path"],[10,1,1,"","blackhole_identity"],[10,1,1,"","deregister_announce_handler"],[10,1,1,"","has_path"],[10,1,1,"","hops_to"],[10,1,1,"","next_hop"],[10,1,1,"","next_hop_interface"],[10,1,1,"","register_announce_handler"],[10,1,1,"","request_path"],[10,1,1,"","unblackhole_identity"]]},"objnames":{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","property","Python property"],"3":["py","attribute","Python attribute"]},"objtypes":{"0":"py:class","1":"py:method","2":"py:property","3":"py:attribute"},"terms":{"":[0,1,3,4,7,9,10,13,14,15,16],"0":[1,3,4,7,10,13,14,15],"00":[4,13,14],"00000000":13,"00000100":13,"00000111":13,"01":[4,13],"0100":4,"01010000":13,"02":3,"03":4,"04":4,"05":[1,4],"0536":14,"06915":7,"08":[1,14],"09":4,"0d7334d411d00120cbad24edf355fdd2":4,"0f4259fef4521ab75a3409e353fe9073eb10783b4912a6a9937c57bf44a62c1":14,"0x0101":1,"0x20":1,"0x7d":1,"0x7e":1,"0x91c421ddfb8a30a49a71d63447ddb54cebe3465":12,"0xf000":[1,10],"1":[1,3,4,7,10,13,14,16],"10":[4,7,13,14],"100":[1,7,13],"1000":1,"10000000":13,"1024":[1,7],"109":16,"11":[4,13],"115":13,"115200":[1,7,14],"1178a8f1fad405bf2ad153bf5036bdfd":14,"118":7,"12":[3,4,7,14],"1200":13,"125":7,"125000":7,"127":7,"128":[7,9,10,13],"13":14,"13425ec15b621c1d928589718000d814":[9,13],"14":[4,7],"15":[4,7],"150":[7,14],"150m":7,"153cb870b4665b8c1c348896292b0bad":4,"15kb":16,"15m":14,"16":[4,7,9,13,14,16],"1625":7,"1625000":7,"167":13,"168":16,"17":14,"1716230400":4,"1726dbad538775b5bf9b0ea25a4079c8":14,"18":[4,14],"1800":10,"187":14,"192":16,"1a54d64db7e8beca6f2c6cd17b0cb479":4,"1b03013c25f1c2ca068a4f080b844a10":14,"1h":14,"2":[1,3,4,7,10,13,14],"20":[4,7,13,14],"200":[7,14],"2005":0,"201":7,"2016":[8,15],"2023":[3,14],"2024":4,"2025":4,"2026":[4,8,16],"21":3,"21a8daa6d9c3d3b8aab6e94b6bcb0e33":4,"22":[4,7],"2225fdeecaf6e2db4556c3c2d7637294":14,"23":[4,14],"2316":14,"23h":14,"24":[4,7,14],"2400000000":7,"25":[1,6,15],"250":16,"255":[7,14],"25519":10,"256":[4,7,9,10,13,14,15],"2592000":10,"27":14,"29":7,"297":[13,15],"29716":7,"2b489d06eaf7c543808c76a5332a447d":14,"2b9ec651326d9bc274119054c70fb75":14,"2d03725b327348980d570f739a3a5708":14,"2d882c5586e548d79b5af27bca1776dc":14,"2f":1,"2owjajquafianpecac":3,"3":[1,3,4,7,13,14,15],"30":[4,7,10,14],"30602def3b3506a28ed33db6f60cc6c9":14,"32":[3,4,10,13],"3278":7,"327c1b2f87c9353e01769b01090b18f2":16,"32m":14,"33":7,"34":[7,16],"360":[4,7,10],"3600":[1,3,7],"37":4,"37428":14,"37429":14,"38":[4,14],"383":10,"3865":14,"399ea050ce0eed1816c300bcb0840938":14,"3a4f8b9c1d2e3f4g5h6i7j8k9l0m1n2o":14,"3b87":7,"4":[4,10,13,14],"40m":14,"42":4,"4242":[3,7],"4251":7,"42671":7,"430":13,"4343":7,"44":15,"44318":7,"45":[1,4,13],"46":14,"464":10,"465":13,"469":14,"48555":7,"49":14,"49555":7,"4965":14,"4e":7,"4faf1b2e0a077e6a9d92fa051f256038":13,"4g":16,"4ghz":7,"5":[1,4,7,10,13,14,15,16],"500":[7,10,13,15,16],"5001":7,"50824b711717f97c2fb1166ceddd5ea9":4,"51":[7,13],"512":[7,10,13,15],"52":14,"521c87a83afb8f29e4455e77930b973b":14,"5245a8efe1788c6a1cd36144a270e13b":14,"53":4,"55":7,"56":14,"564":1,"56m":14,"5757":7,"5858":7,"59":14,"5caf":7,"5d78":7,"5urvjicpzi7q3ybztsef4i5ow2aq4soktfj7zedz53s47r54jnqq":7,"6":[3,4,7,10,14],"60":[1,7,14],"600":7,"63":14,"64":[3,13,14],"68a4aa91ac350c4087564e8a69f84e86":14,"7":[3,7,13,14],"71":16,"71e5":7,"72":7,"720":[7,10],"7200":7,"73":[7,14],"73cbd378bb0286ed11a707c13447bb1":14,"74":14,"74195":7,"781":14,"7822":14,"7a55144adf826958a9529a3bcf08b149":14,"8":[1,7,14],"80":[12,14],"8001":7,"809":14,"83":[13,14],"83b7328926fed0d2e6a10a7671f9e237":16,"84fpy1qbxhcgdseepynmhthcrgmx4nffbytz2gkytoqhvvhjp8eaw1z1eedrnkd19b3b8nilcgvxzkv17ummmeescrpya5w":12,"86":14,"865":7,"865600000":7,"867":7,"867200000":7,"868":13,"88":7,"89":7,"8a37cdd16938ce79861561adbd59023a":4,"8dd57a738226809646089335a6b03695":14,"8f3a21c9d84e927b":4,"8f7e6d5":4,"8f7e6d5c8f7e6d5c8f7e6d5c8f7e6d5c8f7e6d5":4,"9":[3,4,14],"90":4,"900":[13,14],"9037":14,"921600":14,"941bed5e228775e5a8079fc38b1ccf3f":14,"959e10e5efc1bd9d97a4083babe51dea":4,"96":13,"9600":1,"9710b86":4,"9710b86ba12c42d1d8f30f74fe509286":4,"9710b86ba12c4f2":4,"984b74a3f768bef236af4371e6f248cd":14,"99":13,"99714":7,"9a":4,"9fb6d773498fb3feda407ed8ef2c3229":14,"9h":14,"A":[0,1,3,4,6,7,8,9,10,11,13,14],"AND":8,"AS":8,"And":[0,1,16],"As":[0,3,4,5,7,10,11,12,13,14,15],"At":[3,13],"BE":8,"BUT":8,"Be":[4,10,14,16],"But":[0,12,13,16],"By":[0,1,3,4,7,10,13,14,16],"FOR":8,"For":[0,3,4,6,7,9,10,13,14,15],"IN":[1,8,10],"If":[0,1,3,4,5,7,9,10,11,12,13,14,15,16],"In":[0,1,3,4,5,6,7,9,10,11,13,14,15],"It":[0,1,3,4,5,7,9,10,11,13,14,15,16],"NO":8,"NOT":8,"No":[1,3,7,9,13,14,15,16],"Not":6,"OF":8,"OR":8,"Of":[9,13],"On":[0,1,3,4,7,9,14,16],"One":[3,4,5,7,10,13,16],"Or":[4,6,7,13,14,15],"Such":[0,7],"THE":8,"TO":8,"That":[0,4,11,13,16],"The":[1,3,5,6,7,8,9,10,11,12,15],"Then":[0,1,3],"There":[0,3,9,13,14,16],"These":[0,3,4,7,9,10,11,13,14],"To":[1,3,4,5,6,7,9,13,14,15],"WITH":8,"Will":10,"With":[0,6,7,9,11,13,14,16],"_":13,"__":13,"______":13,"_______":13,"________":13,"________________":13,"__future__":1,"__init__":[1,10],"__main__":1,"__name__":1,"__str__":1,"_no_us":10,"a1b2c3d4e5f686ba12c42d1ba12ef1aa":4,"a4d":7,"a79f":7,"aarch64":3,"ab":1,"abandon":0,"abc":4,"abil":[0,3,4,5,6,8,14,15],"abl":[0,1,3,4,7,10,13,14],"abolish":16,"abort":[0,1,4,7],"about":[1,3,4,5,7,9,10,13,14,16],"abov":[3,4,5,7,8,13,14],"absolut":[7,12,15,16],"abstract":[9,10,13,16],"abstractmethod":10,"abund":[5,16],"abus":14,"academ":0,"accept":[0,4,7,10,12,13,14,16],"accept_al":[1,10],"accept_app":10,"accept_non":10,"accepts_link":10,"access":[0,3,6,7,9,10,14,16],"access_point":[7,9],"accid":[11,16],"accommod":[10,13],"accomod":16,"accord":[1,3,4,9,13],"accordingli":[1,7],"account":[0,9,10,16],"achiev":[0,3,7,9,10,13,15],"acknowledg":[9,15],"across":[0,1,4,5,7,9,10,13,14,16],"act":[0,3,7,10,13,14,16],"action":[0,1,8,14],"activ":[0,1,3,4,7,10,13,14],"actor":[0,13,14,16],"actual":[0,1,3,4,7,9,13,14,16],"ad":[0,1,4,5,6,7,9,10,11,13,14,15,16],"adapt":[3,5,16],"add":[0,1,3,4,7,9,10,14],"add_argu":1,"add_message_handl":[1,10],"add_ready_callback":10,"addict":16,"addit":[4,5,7,9,10,11,13,14,15],"addition":[3,4,5,7,13],"addr":14,"address":[0,1,3,4,6,7,10,13,14,15],"adher":[7,10],"adjust":[3,4,10,14,16],"adm":4,"admin":[4,7],"administ":4,"administr":[4,9,11,13,14,16],"adopt":13,"adress":[10,13],"advanc":[11,13],"advantag":10,"advers":15,"adversari":[3,9,12,16],"advertis":[1,7,10],"advic":12,"advis":[7,13],"ae":[10,13,15],"af73":7,"affect":[3,7,16],"affili":[0,11],"affin":7,"afford":9,"after":[1,3,4,7,9,10,13,14],"afterthought":16,"ag":0,"again":[7,13,14],"against":[0,3,4,7,13,16],"agenc":[6,13],"agent":[13,16],"agnost":[9,13],"agnostic":[13,16],"ago":14,"agreement":[0,16],"ahead":9,"ai":16,"aim":[0,3,6,13],"air":[3,5],"airmax":5,"airtim":[7,9,16],"airtime_limit_long":7,"airtime_limit_short":7,"akin":13,"algorithm":[0,8,9,16],"alia":4,"alias":6,"aliased_nam":4,"alic":[4,13],"alien":16,"align":[3,14,16],"aliv":[10,13],"all":[0,1,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"allevi":5,"alloc":[7,9,10,13,14],"allow":[0,1,3,4,5,7,9,10,11,13,14,15,16],"allow_al":[1,10],"allow_list":10,"allow_non":10,"allowed_hash":14,"allowed_ident":14,"allowed_list":10,"allowedsignersfil":4,"almost":[0,5,7,13,14,16],"alon":7,"along":[4,7,10,13,14],"alongsid":[4,9],"alreadi":[1,3,4,5,9,10,11,13,14,16],"also":[0,1,3,4,5,6,7,9,10,11,13,14,15,16],"alter":[3,10,13],"altern":[1,3,4,7,14],"although":[3,13,15],"altitud":7,"alwai":[0,3,4,7,9,10,13,14,16],"am":16,"amateur":[7,15],"among":[0,16],"amongst":8,"amount":[1,7,9,10,13,15,16],"amplifi":0,"amsterdam":[7,14],"an":[0,1,3,4,5,7,8,9,10,11,13,14,15,16],"analog":[11,16],"analysi":[0,4],"analyt":12,"analyz":0,"anchor":6,"android":[6,7,11,14],"ani":[0,1,3,4,5,7,8,9,10,11,12,13,14,15],"annonuc":7,"annot":1,"annouce_cap":7,"announc":[3,4,6,9,10,11,14],"announce_cap":[7,10],"announce_handl":1,"announce_interv":[4,7],"announce_packet_hash":10,"announce_rate_grac":[3,7],"announce_rate_penalti":[3,7],"announce_rate_target":[3,7],"announced_ident":[1,10],"announceloop":1,"announces_from_intern":7,"announces_to_intern":7,"announcesampl":1,"annoy":14,"anonym":[3,9,10,13,15],"anoth":[4,7,9,10,13,14,16],"answer":[13,14,16],"antenna":[5,16],"anticip":4,"anxieti":16,"anymor":[3,16],"anyon":[0,1,3,4,5,7,9,10,13,14,16],"anyth":[0,4,5,7,11,13,14,15,16],"anywai":7,"anywher":[0,1,7,16],"ap":7,"api":[3,4,6,13,15,16],"apk":3,"app":[1,3,10,13,16],"app_and_aspects_from_nam":10,"app_data":[1,10],"app_nam":[1,10],"app_timeout":1,"appar":0,"appear":16,"append":[1,13,14],"appli":[0,4,7,10,13,16],"applic":[0,1,7,9,10,11,13,14,15,16],"appreci":4,"approach":[0,3,5,9,13,14],"appropri":[0,4,7,9,16],"approv":[0,9,13,16],"approxim":[7,14],"april":3,"apt":3,"ar":[0,1,3,4,5,7,9,10,11,12,13,14,15,16],"arbit":16,"arbitrari":[4,10,13,14,15],"arch":[3,16],"architect":[12,16],"architectur":[3,6,11],"archiv":[4,6,11],"area":[0,3,5,7,9,13,15],"arg":[1,14],"argon":1,"argpars":1,"argument":[1,4,10,14],"argumentpars":1,"aris":8,"arm64":6,"armi":16,"armor":[4,16],"around":[3,7,13,16],"arrai":3,"arrang":0,"arriv":[1,7,13,16],"art":16,"artifact":[4,6],"artifacts_dir":4,"artifici":8,"arx":14,"ascii":4,"ask":[1,3,5,10,11,16],"aspect":[1,3,5,7,9,10,13,14],"aspect_filt":[1,10],"assert":[0,16],"assign":[1,9,13,14,16],"assist":11,"associ":[4,8,10,13,14],"assum":[7,9,13,16],"assumpt":[9,12,16],"assuredli":16,"asymmetr":[13,14,15],"asymmetri":0,"asynchron":[9,16],"atop":0,"attach":[0,11,14],"attached_interfac":10,"attack":3,"attain":3,"attempt":[1,3,4,5,7,10,14],"attent":[0,12,16],"attest":4,"attribut":[0,6,10],"atx":14,"auth":14,"authent":[0,4,7,9,10,11,13,14,15],"author":[0,6,8,13,14,16],"authoris":14,"authorit":[4,13,15],"authorship":0,"auto":[3,4,5,6,10,13,14],"auto_compress":10,"autoconfigur":15,"autoconnect_announces_to_intern":14,"autoconnect_discovered_interfac":[7,14],"autoconnect_interface_grav":7,"autoconnect_interface_mod":14,"autodiscov":7,"autoinstal":[5,14],"autointerfac":[3,5,7,14],"autom":[0,3,4,5,6,11,12,13],"automat":[1,3,6,7,9,10,11,13,14,15,16],"autonom":[0,9,13,16],"autonomi":[0,15,16],"avail":[0,1,3,4,5,6,7,9,10,11,13,14,15,16],"averag":13,"avoid":[5,13,14],"awai":[0,1,7,13,14,16],"await_path":10,"awar":[3,4,7,13],"ax":[6,15],"ax25kissinterfac":7,"b":[1,4,14],"b32":7,"back":[0,1,4,7,13,15,16],"backbon":[5,6,9,14,16],"backboneinterfac":[3,7,14],"backend":[7,13],"background":[3,7,14],"backhaul":[5,9],"backup":[0,14],"balanc":7,"band":[5,13,16],"bandwidth":[3,6,7,9,10,11,13,14,15],"bar":16,"bare":[0,1,4,7,16],"barrier":[0,7,13,16],"base":[0,4,6,7,9,10,11,13,14,15,16],"base32":[7,14],"base64":[4,14],"bash":[7,14],"bash_sourc":4,"basi":[0,7,10,13,14,15],"basic":[1,3,6,7,9,10,14],"batch":4,"batteri":16,"baud":[7,14],"baud_flash":14,"baudrat":1,"bc1pgqgu8h8xvj4jtafslq396v7ju7hkgymyrzyqft4llfslz5vp99psqfk3a6":12,"bc7291552be7a58f361522990465165c":[14,15],"beacon":7,"beast":16,"beat":16,"beauti":[0,11],"becam":0,"becaus":[0,4,9,13,16],"becki":1,"becom":[0,1,3,4,7,9,13,16],"been":[0,1,3,4,5,7,9,10,11,12,13,14,15,16],"befor":[1,3,4,7,9,10,12,13,14,16],"beg":16,"begin":[1,5,10,16],"begun":10,"behalf":[7,9],"behav":[5,11],"behavior":[7,16],"behaviour":[3,7,14],"behind":[3,7,12,13,16],"being":[0,3,4,7,10,13,16],"beings":[0,8,13],"belief":13,"believ":[0,16],"belong":[7,9,13,14,16],"below":[5,7,14],"bend":16,"benefici":[7,14],"berlin":16,"best":[3,9,10,13,16],"better":[0,3,7,9,12,13,16],"between":[0,1,7,9,10,11,13,14,16],"beyond":[0,4],"bi":[10,13],"bidirect":13,"big":16,"bill":16,"billion":[9,13],"billionair":16,"bin":[3,7,14],"binari":[1,3,7,9,10,13,14,16],"bind":[6,7],"bit":[1,3,4,7,9,10,11,13,14,15,16],"bitcoin":12,"bitrat":[1,7,10],"black":0,"blackhol":[3,6,9,10,13],"blackhole_ident":10,"blackhole_sourc":[10,14],"blackhole_update_interv":14,"blackholed_ident":14,"blackholeupdat":14,"ble":7,"blindli":[14,16],"blob":[1,4,13],"block":[3,4,6,9,10,11,13,14,16],"block_fast_flap":7,"blockchain":16,"blocklist":14,"blood":16,"blueprint":16,"bluetooth":14,"board":[3,6,7,11,13,15],"boat":16,"bob":4,"bobs_nod":4,"bogu":7,"boil":5,"bond":16,"book":16,"bookworm":6,"bool":10,"boot":[3,14],"bootstrap":[6,7,14],"bootstrap_onli":[3,7],"borrow":16,"bot":11,"both":[0,1,3,4,5,7,9,10,11,13,14,15],"bounc":[3,16],"bound":[9,16],"boundari":[0,4,7,9,13],"box":[0,5],"branch":[0,4,14],"breadcrumb":4,"break":[3,10,13,16],"breath":[3,16],"breviti":14,"bridg":[5,7],"briefli":[5,13],"bring":[7,14],"brittl":[3,16],"broad":[3,5],"broadcast":[3,6,7,9,10,13,14,16],"broadcast_destin":1,"broadcastloop":1,"broader":[3,13],"broken":[3,7,16],"brought":[7,14],"brows":[0,4,11,16],"browser":[4,11,16],"buffer":[6,7,10,15],"bufferedread":10,"bufferedrwpair":10,"bufferedwrit":10,"bufferexampl":1,"bug":[4,11,12],"bui":16,"build":[0,1,4,5,6,7,11,13,15,16],"builder":16,"built":[0,3,7,9,11,13,14,15,16],"bulletin":11,"bundl":1,"bureaucraci":16,"bureaucrat":[15,16],"burst":[6,14],"busy":0,"button":16,"bw":14,"bypass":[7,12,16],"byte":[1,6,9,10,13,14,15],"bytes":1,"c":[1,4,8,14],"c50cc4e4f7838b6c31f60ab9032cbc62":14,"c89b4da064bf66d280f0e4d8abfd9806":14,"cabl":[7,16],"cach":[7,9,14],"cafe":16,"cage":16,"calcul":[9,10,13,14],"call":[0,1,9,10,11,13,15,16],"callabl":[1,10],"callback":[1,10],"callsign":7,"came":4,"camp":0,"can":[0,1,3,4,5,6,7,9,10,11,12,13,14,16],"cancel":[4,10],"candid":9,"cannot":[0,1,3,4,7,9,15,16],"cap":7,"capabl":[0,1,3,7,9,13],"capac":[3,5,9,10,13],"capit":[0,16],"captur":[0,16],"car":9,"carambola":1,"card":[0,16],"care":[0,3,4,9,10,14,15,16],"carefulli":3,"cargo_build_target":3,"carri":[0,7,9,10,13,14,15,16],"carrier":[6,9,15],"case":[0,1,3,4,5,7,9,13,14],"castl":16,"cat":14,"catastroph":0,"categori":5,"caus":[3,7],"caution":7,"cb":[10,13],"cbc":[13,15],"cd":4,"cdma":7,"ceas":[0,16],"cede":0,"cell":9,"cellular":16,"cement":16,"censor":[0,13,14,16],"censorship":[13,15],"center":6,"central":[0,3,4,5,7,9,11,13,14,16],"centralis":13,"centric":0,"centuri":0,"ceo":16,"certain":[1,7,9,12,13,14,16],"certif":16,"certifi":0,"chain":[4,7,16],"challeng":[3,11,13,16],"chanc":5,"chang":[0,1,3,4,7,10,13,14,15,16],"channel":[0,3,4,6,7,9,10,12,13,15,16],"channelarg":1,"channelexampl":1,"chaotic":16,"chapter":[0,3,4,5,7,9,10,11,13,14,15],"charact":[1,4,7,14],"characterist":[7,9,13,16],"charg":8,"chart":4,"charter":13,"chase":16,"chat":6,"cheap":[5,7,13],"cheapli":3,"check":[1,3,4,10,13,14,16],"checksum":[4,10,15],"chmod":4,"choic":[3,9,16],"choke":16,"choos":[0,1,3,7,11,13,16],"chose":13,"chosen":13,"chunk":1,"cific":7,"ciphertext":10,"ciphertext_token":10,"circl":16,"circumst":[12,13,16],"citi":16,"cl":1,"claim":[4,8,13],"clariti":16,"class":[1,9,10,15],"clear":[1,7,10,14,16],"clear_default_app_data":10,"clear_screen":1,"clearli":16,"click":4,"client":[0,1,4,5,6,10,14,16],"client_buffer_readi":1,"client_config":4,"client_connect":1,"client_disconnect":1,"client_ident":[1,4],"client_loop":1,"client_message_receiv":1,"client_packet_receiv":1,"client_request":1,"climat":16,"clone":[4,13],"close":[1,9,10,14],"closed_callback":10,"closer":[11,13],"closest":13,"cloth":16,"cloud":[0,6,7,11],"cluster":[0,13],"co":[4,5,7,15],"code":[0,3,4,5,6,7,9,11,12,14,15,16],"codic":0,"codingr":7,"coexist":9,"coffe":16,"coher":16,"collabor":[0,4,13,14],"collaps":[0,3,16],"collect":[0,3,12],"collis":9,"colon":16,"color":4,"com":[1,4,12,16],"combin":[0,3,4,6,11,13,14,16],"combinatori":16,"come":[0,3,7,9,13,16],"comma":[7,14],"command":[0,1,3,6,7,11,14],"commend":16,"comment":[0,4,7,14],"commerci":16,"commit":[0,3,6,11],"committe":16,"common":[0,1,3,5,6,9,13,14,15,16],"commonli":[4,5,7],"commun":[0,1,3,4,6,7,9,10,11,12,13,14,15,16],"communica":7,"compani":16,"compar":[9,16],"compass":16,"compat":[0,1,3,4,5,7,10,11,13,14,15],"compet":[0,16],"compil":3,"complain":16,"complet":[0,1,3,4,5,7,9,10,11,13,14,15],"complex":[0,3,7,12,13,16],"compli":9,"compon":[5,12,13,16],"compos":[4,6,13],"comprehens":[0,11,12],"compress":[1,10,13,14,15],"compromis":[0,13,16],"comput":[0,3,7,13,15,16],"computation":[7,14],"concaten":[10,14],"conceiv":[0,3,5],"concept":[0,6,13,14,16],"conceptu":[0,4,6],"concern":16,"concert":13,"conclud":[1,10],"concret":16,"concurr":[5,13,14],"condit":[3,8,13,15,16],"conduct":0,"conduit":16,"conf":[3,11],"config":[1,3,4,7,9,14,16],"configarg":1,"configdir":10,"configobj":4,"configpath":1,"configur":[0,1,3,5,6,9,10,13,15],"configuraion":5,"configuraiton":14,"configure_devic":1,"confirm":[4,9,13,15,16],"conflict":[3,9],"conform":0,"confront":16,"confus":[5,13],"congest":13,"conglomer":16,"conjunct":7,"connect":[0,1,4,5,6,8,10,12,13,14,15,16],"conscienc":16,"conscious":0,"conscript":16,"consent":0,"consequ":[0,9,13],"conserv":7,"consid":[1,3,7,10,11,13,14,15,16],"consider":[6,13],"consist":[4,13,14],"consol":14,"constant":[0,10,16],"constantli":[13,16],"constitut":[0,3,13],"constrain":[9,10],"constraint":16,"construct":[0,4,13,15,16],"constructor":1,"consum":[4,9,10,16],"consumpt":[9,16],"contact":[7,9,11,13,16],"contain":[0,1,4,7,9,10,13,14],"contempl":16,"contemporari":0,"contend":13,"content":[0,1,3,4,9,11,14],"context":[3,13,14,16],"contin":[1,3,16],"continu":[0,4,7,10,12,14,15,16],"contract":8,"contrari":16,"contrast":0,"contribut":[0,6,8,9,12],"contributor":0,"control":[0,1,3,4,5,6,9,10,11,13,14,15,16],"convei":[1,16],"conveni":[0,1,4,14,16],"convent":[1,9],"converg":[3,9,13,16],"convers":[0,4,11,13,16],"convert":[0,4],"cook":3,"coordin":[7,9,10,13,15,16],"copi":[0,4,8,14],"copyright":[0,8],"core":[0,9,13,14,15,16],"corner":16,"corpor":[0,16],"correct":[0,1,4,7,9,13],"correctli":[1,4,9],"correspond":[4,9,13,16],"corrupt":[0,4],"cost":[5,6,7,13,15],"could":[0,1,3,7,9,10,13,14,15,16],"count":[4,11,13,16],"counter":1,"cours":[3,4,7,9,13,16],"coven":16,"cover":[3,4,5,9,10,13,15],"coverag":[7,9],"cpu":[1,7,9,13],"cpuinfo":14,"cr":14,"craft":[0,4,16],"craftsman":16,"crash":16,"creat":[0,1,6,7,9,10,11,14,15,16],"create_bidirectional_buff":[1,10],"create_kei":10,"create_read":10,"create_receipt":[1,10],"create_writ":10,"creation":[0,6,8,9,11,13,14,15],"creativ":[0,16],"creator":[0,6,13,16],"credenti":[7,13],"critic":[0,9,13,14],"cron":0,"cross":[7,11],"crowd":16,"crucial":9,"cruft":16,"cryptograph":[0,3,6,7,9,14,15,16],"cryptographi":[0,3,13,15],"crystal":16,"ctrl":1,"cull":10,"culmin":16,"cultur":0,"cumbersom":4,"curl":7,"current":[0,1,3,4,6,7,10,11,14,16],"current_download":1,"current_filenam":1,"current_ratchet_id":10,"curv":[9,10,13,15],"curve25519":[9,10,13,15],"custodian":16,"custom":[5,6,10,11,13,15],"custom_network_nam":7,"customis":7,"cut":16,"cynic":16,"d":[4,14],"d09285e660cfe27cee6d9a0beb58b7e0":4,"d56a4fa02c0a77b3575935aedd90bdb2":14,"daemon":[1,3,7,10,11,14],"dai":[4,10,11,16],"daili":4,"damag":[0,8,16],"danc":16,"danger":16,"dark":16,"data":[0,1,3,4,5,6,7,9,10,13,15,16],"data_buff":1,"data_port":7,"databas":[0,11,14,16],"databit":[1,7,14],"datacent":3,"datar":7,"dataset":[8,16],"date":[1,3,4,11,14],"datetim":1,"db":[1,14],"dbm":[1,7,14],"deadlin":0,"deal":[7,8],"death":6,"debian":[6,13,14],"debug":[3,14],"decad":[0,5,12,16],"decentr":[3,6,7,14],"decentralis":15,"decid":[0,7,9,10,13,16],"decim":7,"decis":[0,4,7,9,13,16],"declar":13,"decod":[1,7,14],"decoupl":0,"decreas":[4,7,14],"decrypt":[7,9,10,13,14],"dedic":[4,7,13,15,16],"deep":[3,16],"deepli":[0,16],"def":[1,4],"default":[1,3,4,5,7,9,10,11,13,14],"default_ar_grac":7,"default_ar_penalti":7,"default_ar_target":7,"default_grav":7,"default_ifac_s":1,"default_per_hop_timeout":10,"defin":[1,4,7,10,13,14,15,16],"definit":[1,3,4,13,14,16],"defunct":14,"degrad":9,"degre":7,"delai":[7,11,13,14,16],"deleg":[0,4,13],"delet":[0,4,16],"delimit":1,"deliv":[1,3,9,10,11,16],"deliveri":[0,1,4,9,10,11,15],"demand":[4,10,16],"demonstr":[0,1,3,7,16],"deni":[0,4,16],"denomin":0,"depend":[0,1,4,5,6,7,9,10,13,14,16],"deploi":[13,16],"deploy":4,"depriorit":16,"depth":16,"deregist":10,"deregister_announce_handl":10,"deregister_request_handl":10,"deriv":[3,9,10,13,15],"describ":[4,5,7,10,13],"descript":[1,4,14],"descriptor":1,"deseri":1,"deserializ":1,"design":[0,3,4,5,6,7,9,11,12,13,14,15],"desir":[1,5,7,13],"desk":16,"desktop":[7,11],"dest_len":1,"destin":[1,3,6,10,14,16],"destination_1":1,"destination_2":1,"destination_clos":1,"destination_hash":[1,4,10,14],"destination_hexhash":1,"destroi":[0,16],"destruct":16,"detach":[4,7],"detail":[0,1,3,4,6,7,10,14,15],"detect":[1,4],"determin":[3,9,10,13,16],"determinist":4,"detriment":14,"dev":[1,3,4,7,14],"devel":3,"develop":[4,5,6,8,10,11,12,13,14,15,16],"devic":[1,3,6,7,9,10,11,13,14,16],"dh":10,"dhcp":[5,7,9,14],"di":16,"dict":1,"dictat":[14,16],"dictatorship":16,"dictionari":14,"did":[0,1,11,16],"diff":4,"differ":[0,1,3,4,5,7,9,10,11,13,14,15,16],"differenti":14,"diffi":[9,13],"difficult":[3,5,14],"difficulti":[7,14],"digit":[0,3,5,13,15,16],"digniti":[0,16],"dilut":0,"dinner":16,"dir":[1,4],"dire":5,"direct":[0,1,3,4,5,9,10,11,13,14],"direction":13,"directli":[0,3,4,5,7,8,9,10,11,13,14,15,16],"directori":[1,3,4,7,9,14,16],"dirnam":4,"disabl":[7,13,14],"disappear":[7,14,16],"disassoci":13,"discard":[3,10,13],"discern":0,"disciplin":[0,16],"disconnect":[1,3,6,7],"discourag":0,"discov":[0,3,6,7,9,10,11,13,16],"discover":[3,6,14],"discover_interfac":14,"discovered_interfac":10,"discoveri":[3,4,6,10,13,14],"discovery_bandwidth":7,"discovery_encrypt":7,"discovery_frequ":7,"discovery_lxmf_address":7,"discovery_modul":7,"discovery_nam":7,"discovery_port":7,"discovery_scop":7,"discovery_stamp_valu":7,"discret":0,"discrimin":9,"discuss":[0,4,5,13],"disk":[1,4,10,14],"displai":[1,4,7,9,11,13,14],"disrupt":[0,7],"dissemin":0,"dissolv":[9,16],"dist":4,"distanc":[5,13,14],"distant":[3,10,13],"distinct":[0,7,9,13,16],"distinguish":[9,13],"distribut":[1,4,6,8,9,10,11,13,14,15,16],"dive":3,"diverg":0,"divers":0,"divid":10,"divmod":1,"dn":[5,7,11,16],"dna":16,"dnf":3,"do":[0,1,3,4,5,7,8,9,10,13,14,16],"doc_id":4,"document":[0,3,6,8,10,11,13,14,15,16],"doe":[0,1,3,4,5,6,7,10,11,13,14,16],"doesn":[0,7,9,16],"dollar":16,"domain":[0,3,6,7,13,14,15],"domin":16,"don":[1,3,4,9,10,13,14,16],"donat":6,"done":[1,3,4,7,13,14,16],"door":16,"dot":[13,14],"doubt":3,"dowload":3,"down":[0,1,5,7,10,14,16],"download":[0,1,3,4,7,9,11,14],"download_began":1,"download_conclud":1,"download_finish":1,"download_start":1,"download_tim":1,"downstream":14,"drag":11,"drain":7,"drastic":14,"draw":16,"drawn":16,"drive":[0,12],"driver":[14,15],"droid":3,"drone":16,"drop":[4,7,9,10,11,13,14,16],"drown":0,"dsrdtr":1,"dual":[5,14],"dublin":14,"due":[0,1],"dumb":16,"dump":[7,14],"duplex":[13,15],"durabl":0,"durat":14,"dure":[4,14],"dynam":[0,3,4,7,11,14,16],"dysfunct":12,"dysregul":0,"e":[1,4,14],"e5c032d3ec4e64a6aca9927ba8ab73336780f6d71790":14,"e702c42ba8":14,"e7536ee90bd4a440e130490b87a25124":14,"each":[0,1,3,4,7,9,10,11,13,14],"earli":16,"earlier":13,"eas":[7,13],"easi":[3,4,5,7,11,13,14,15],"easier":[3,4,7,9,14,15],"easiest":[3,5,7,13],"easili":[0,3,4,7,9,13,14,15,16],"eastern":13,"ec_pr_freq":7,"ecdh":[13,15],"echo":[4,6],"echo_destin":1,"echo_request":1,"econom":0,"economi":16,"ecosystem":[0,3,7,11,13,14,16],"ed25519":[0,4,13,15],"edit":[3,4,14],"editor":[4,14],"ee":4,"eeprom":14,"effect":[0,4,7,13,14],"effici":[1,3,7,9,10,11,13,14,15,16],"effort":[5,10,16],"effortlessli":11,"eg":14,"egress":7,"egress_control":7,"ei":1,"either":[3,4,5,9,10,13,14,16],"elaps":[4,7],"electromagnet":16,"eleg":16,"element":[9,16],"elev":0,"elif":1,"elimin":[0,9,16],"ellipsoid":7,"ellipt":[9,10,13,15],"els":[0,1,9,11,12,13,15,16],"email":[0,4,11],"emb":4,"embed":[0,4,5],"embrac":16,"emerg":[0,6,11],"emiss":11,"emot":0,"emploi":[0,5,13],"empow":15,"empti":[1,6,7,16],"emul":[3,14],"enabl":[0,1,3,5,6,9,10,11,13,14,15,16],"enable_ratchet":10,"enable_remote_manag":14,"enable_transport":[7,13,14],"encapsul":[7,15],"enclos":4,"encod":[1,4,10,11,14,16],"encount":[3,9],"encourag":[0,3,16],"encrypt":[0,1,3,4,6,7,9,10,11,13,14,15],"encrypted_mdu":10,"end":[1,4,7,9,10,11,13,15],"endeavor":0,"endless":[7,16],"endow":0,"endpoint":[1,9,10,11,13,16],"energi":[3,16],"enforc":[7,10,13,14],"enforce_ratchet":10,"engag":[0,16],"engin":[0,3,11,12,16],"enhanc":13,"enjoy":0,"enough":[0,3,5,7,11,13],"ensur":[0,1,3,4,7,9,10,11,13,14,15,16],"ensurepath":3,"enter":[0,1,14],"entir":[0,1,3,4,7,9,10,11,13,14,15,16],"entiti":[0,9,13,14,16],"entitl":0,"entri":[0,1,3,13,14,16],"entropi":16,"entrypoint":[6,7,14],"enumer":1,"envelop":[4,10,16],"environ":[0,3,4,6,7,9,12,13,14],"environment":13,"environmentlogg":13,"eof":7,"ephemer":[0,9,10,13,15],"epub":6,"equal":[0,9,10,13,16],"equip":[7,9,13],"equival":[4,7,16],"era":16,"erod":16,"erron":12,"error":[1,3,4,7,12,14,16],"esc":1,"esc_mask":1,"escap":[1,14],"esoter":0,"esp32":5,"especi":[3,4,5,7,14],"essenti":[0,3,4,7,11,13,14,16],"establish":[0,1,3,7,9,10,11,14,15,16],"established_callback":10,"establishment_timeout_per_hop":10,"estim":10,"etc":[4,14],"eth0":7,"eth1":7,"ether":16,"ethereum":12,"ethernet":[3,6,7,9,11,13,15,16],"ethic":6,"evalu":0,"evapor":16,"even":[0,1,3,4,7,9,10,11,13,14,15,16],"event":[7,8,16],"eventu":10,"ever":13,"everi":[0,1,3,4,7,9,10,13,14,16],"everydai":3,"everyon":[0,3,4,11,12,13,16],"everyth":[0,1,4,9,11,12,13,16],"evict":16,"evolv":[0,3,9,13],"exact":[4,5,7,13],"exactli":[4,10,13,16],"exampl":[0,3,5,6,9,10,13,14,15],"example_util":1,"exampleannouncehandl":1,"exampleconfig":[3,14],"exampleinterfac":1,"exce":[1,7,10],"except":[1,7,10],"excess":[7,14],"exchang":[0,9,10,13,15],"exclud":[4,10,13],"exclus":[0,4],"execstart":14,"execstartpr":14,"execut":[0,1,3,4,7,10,14],"exercis":0,"exhaust":[5,11,13,14],"exist":[0,1,3,4,5,6,7,9,11,13,14,15],"exit":[0,1,4,7,10,14],"expand":[4,9,11,13,15],"expand_nam":10,"expans":[0,4,16],"expect":[1,4,7,10,12,13,14],"expens":[5,7],"experi":[9,11,13,14,16],"experienc":1,"expir":[7,10],"expiri":[7,10],"explain":[5,10],"explan":[13,14],"explicit":10,"explicitli":[7,9,13,14],"exploit":0,"explor":[1,11,13,15,16],"export":[3,14],"expos":[7,10,14],"exposur":7,"express":[0,4,8],"extend":[0,1,10],"extens":[4,7,11,14,15],"extern":[0,1,3,4,7,10,14,15,16],"extra":[3,7,14],"extract":[0,4,14,16],"extract_id":4,"extrem":[3,11,13,14,15,16],"f":[1,3,4,14],"f2d31b2e080e5d4e358d32822ee4a3b7":4,"f4":7,"f53a1c4278e0726bb73fcc623d6ce763":14,"fabric":[6,9],"face":[7,11],"facebook":0,"facilit":[11,13],"fact":[0,3,7,15],"factor":[7,10,14],"fade":16,"fail":[0,1,3,4,7,10,16],"failed_callback":[1,10],"failur":[0,3,4,7,10,16],"fake":14,"fallaci":6,"fallback":[4,16],"fallen":16,"fals":[1,7,9,10],"famili":3,"familiar":0,"fantasi":16,"far":[0,3,9,13],"fashion":12,"fast":[6,7,9,10,11,13],"fast_flapping_block_tim":7,"fast_flapping_grac":7,"fast_flapping_threshold":7,"faster":[3,7,13,16],"fastest":[7,13],"fat":16,"favor":3,"favorit":11,"fe80":3,"featur":[3,4,6,7,9,11,12,13,14,15],"feder":[11,13,14,16],"fedora":3,"feed":[0,3,10,16],"feedback":[0,1,6],"feel":[11,16],"fernet":13,"fetch":[0,4,7,14],"few":[0,3,5,7,9,11,13,14,15,16],"fewer":10,"ff":14,"ffcffb4e255e156e77f79b82c13086a6":4,"fi":[4,12],"fiber":[5,16],"fibr":15,"field":[4,13,16],"figur":7,"file":[0,1,3,4,5,7,8,9,10,11,13,14,15],"file_resourc":1,"file_s":1,"filelist":1,"filelist_data":1,"filelist_receiv":1,"filelist_timeout_job":1,"filenam":1,"filesync":6,"filetransf":[6,10],"filter":[0,1,9,13,14],"final":[1,4,10,13,16],"find":[0,4,6,7,11,13,14,16],"find_spec":1,"fine":[0,4,7,14],"fingerprint":16,"finish":6,"finit":16,"fire":16,"firewal":[3,7,9,16],"firmwar":[3,5,13,14],"firmware_hash":14,"first":[0,1,3,4,7,9,10,13,14,16],"fit":[0,1,8,16],"five":[1,16],"fix":[4,6,13,16],"fixed_mtu":7,"flag":[1,3,4,10,13,14],"flap":7,"flash":14,"flasher":3,"flat":16,"flaw":16,"fleet":13,"flesh":16,"flexibl":[3,4,5,7,9,11,14,15],"flexibli":4,"fli":13,"flicker":16,"flight":10,"flip":16,"float":[1,7,10],"flood":[7,14],"flow":[0,1,3,6,7,9,13],"flow_control":7,"fluid":16,"fluiditi":16,"fluidli":16,"flush":1,"focu":[0,14],"focus":[11,13],"folder":[0,1,4],"follow":[0,1,3,4,5,7,8,10,12,13,14,15,16],"font":4,"forbid":16,"forc":[0,1,14,16],"forcibli":[10,14],"foreground":3,"forev":16,"forg":16,"forget":[9,14],"forgotten":0,"fork":[0,6,11],"forker":4,"form":[3,6,7,9,10,13,14,16],"format":[0,1,6,7,11,14,15],"forth":1,"fortifi":0,"fortun":16,"forward":[0,4,6,7,9,10,11,13,14,15],"forward_ip":7,"forward_port":7,"found":[1,3,4,7,10,13,14,16],"foundat":[0,9,12,13,15,16],"four":7,"fragil":[0,16],"frame":[1,7],"framework":11,"free":[3,8,9,11,12,15,16],"freedom":[13,16],"freedv":5,"freeli":13,"freq":14,"frequenc":[3,5,7,13,14],"frequent":[7,9],"friend":[3,16],"friendli":11,"from":[0,1,3,4,5,6,7,8,9,10,11,12,13,14,15],"from_byt":10,"from_fil":10,"from_identity_hash":10,"fromhex":1,"front":[4,13],"frontend":11,"fruit":1,"ftdi_ft230x_basic_uart_43891ckm":14,"fuel":16,"full":[0,1,3,4,7,9,10,11,13,14,15],"full_hash":10,"full_nam":[10,14],"fulli":[1,3,4,5,7,11,13,14,15],"funcion":10,"function":[0,1,3,4,5,6,7,8,9,10,11,12,14,15,16],"fundament":[0,5,9,13,14,16],"furnish":8,"further":[0,3,6,7,14,16],"futur":[0,4,6,9,11,14,16],"fw":14,"g":[1,4,13,14],"ga":1,"gain":[0,5,10,13,16],"galact":13,"gap":3,"gaslit":16,"gatekeep":[0,13,16],"gatewai":[1,3,7,9,13,14,16],"gbp":14,"gear":16,"gen_tim":4,"gener":[0,1,3,4,5,7,9,10,13,14,15,16],"generalis":15,"genuin":14,"geograph":[0,3,7],"geoid":7,"get":[0,1,4,5,6,7,9,10,11,14,16],"get_ag":10,"get_channel":[1,10],"get_config_obj":1,"get_data_s":10,"get_establishment_r":10,"get_expected_r":10,"get_external_ip":7,"get_first_hop_timeout":10,"get_hash":10,"get_inst":10,"get_lowest_interface_bitr":10,"get_mdu":10,"get_medium_path_timeout":10,"get_mod":10,"get_mtu":10,"get_packet_rssi":1,"get_packet_snr":1,"get_part":10,"get_private_kei":10,"get_progress":[1,10],"get_public_kei":10,"get_q":10,"get_random_hash":[1,10],"get_remote_ident":[1,10],"get_request_id":10,"get_respons":10,"get_response_tim":10,"get_rssi":10,"get_rtt":[1,10],"get_seg":10,"get_snr":10,"get_statu":10,"get_transfer_s":10,"geti2p":7,"ghost":16,"ghz":13,"gi":1,"giant":16,"gift":16,"gigabit":[9,16],"gigabyt":15,"git":[0,6,14],"github":[0,1,3,4],"gitlab":0,"give":[3,7,13,14,16],"given":[7,9,10,13,14,16],"global":[1,4,6,7,9,10,13,14,15],"globe":16,"glue":5,"gmail":0,"go":[1,7,9,13,16],"goal":[3,6,7,9,11,15],"goe":16,"good":[0,3,4,5,9,13,14],"goodwil":16,"got":[1,16],"got_respons":1,"govern":[13,16],"government":0,"gp":7,"gpg":4,"gpio":11,"grace":10,"gracefulli":[7,9],"grade":6,"grain":[0,4,14],"grammar":0,"grant":[0,4,8,14,16],"granular":4,"grape":1,"graph":0,"graphic":11,"gratefulli":12,"graviti":[7,16],"great":[3,4,13,14,16],"greater":[4,10,13,14,15],"greatli":[3,7],"green":16,"grep":4,"grid":[11,16],"gross":16,"ground":[0,16],"group":[0,6,7,10,11,13,14],"group_id":7,"group_nam":4,"group_root":4,"groupinstal":3,"grow":[0,3,16],"grown":16,"growth":[0,3],"guarante":[4,9,12,13],"guard":16,"guess":7,"gui":11,"guid":[3,5,11,13],"guidelin":3,"guilt":11,"gun":16,"gw":7,"gz":4,"h":[4,14],"ha":[0,1,4,5,7,9,10,11,12,13,14,15,16],"habit":16,"habitat":16,"hack":15,"had":[0,13],"half":[13,15],"hammer":16,"hand":[1,16],"handheld":13,"handl":[0,1,3,4,5,7,9,10,11,13,14,15],"handler":[1,10,14,16],"handshak":16,"happen":[1,3,4,7,10,13,16],"hard":[3,5,7,16],"hardcod":16,"hardlin":9,"hardwar":[0,1,3,6,7,10,11,13,14,15,16],"harm":[6,8],"harvest":0,"has_path":[1,10],"hasattr":1,"hash":[0,1,4,9,10,13,14,16],"hash1":13,"hash2":13,"hash_from_name_and_ident":10,"hashlib":13,"hashmap":1,"have":[0,1,3,4,5,7,9,10,11,12,13,14,15,16],"hazard":10,"hdlc":1,"he":0,"header":[1,4,7,10,13],"header_1":13,"header_2":13,"health":6,"hear":[13,16],"heard":[0,10,11,13,14],"heart":16,"heavi":16,"height":7,"held":[7,14],"helium":1,"hellman":[9,13],"hello":4,"hello_world":4,"help":[1,3,4,9,12,13,14,16],"helper":[1,4,14],"here":[0,1,3,7,13,14,16],"herebi":8,"heterogen":[3,6,15],"hex":[1,14],"hexadecim":[1,4,13,14],"hexbyt":14,"hf":[11,16],"hidden":14,"hide":[3,16],"hierarch":[15,16],"hierarchi":[6,16],"high":[5,7,9,13,14,15,16],"higher":[0,7,9,15],"highest":10,"highli":[4,7,12,13,14],"highlight":6,"hijack":16,"hint":[1,4],"histor":0,"histori":[0,4,11],"hit":1,"hkdf":13,"hmac":[13,15],"hoc":[15,16],"hold":[7,10,13,16],"holder":[8,9],"hole":16,"hollow":16,"home":[0,3,4,9,11,14,16],"homebrew":7,"hook":[0,4],"hop":[7,9,10,13,14,15,16],"hopefulli":9,"hops_to":10,"host":[0,1,4,6,7,9,11,13,14],"hostil":6,"hostnam":[7,16],"hotspot":16,"hour":[1,4,7,14,16],"hous":[3,16],"how":[0,1,3,4,5,7,9,11,13,14,15,16],"howev":[3,4,7,9,13],"http":[0,1,4,11,12,16],"hub":[7,11,14],"hum":16,"human":[0,1,6,7,8,9,10,12,13],"hundr":[0,9,11,16],"hungri":5,"hw_mtu":1,"hwrev":14,"hz":[7,14],"i":[0,1,3,4,5,6,7,8,9,10,11,12,13,14],"i2p":[3,6,9,11,15],"i2p_tunnel":7,"i2pd":[3,7],"i2pinterfac":[3,7],"ia":14,"ic":5,"ic_burst_freq":7,"ic_burst_freq_new":7,"ic_burst_hold":7,"ic_burst_penalti":7,"ic_held_release_interv":7,"ic_max_held_announc":7,"ic_new_tim":7,"ic_pr_burst_freq":7,"ic_pr_burst_freq_new":7,"icmp":11,"icon":[4,16],"id":[4,7,10,13,14],"id_callsign":7,"id_interv":7,"id_regex":4,"idea":[0,3,4,13,14,16],"ideal":[11,14,15],"ident":[0,1,3,6,7,9,10,11,14,15],"identif":[6,7,15],"identifi":[1,7,9,10,13,14,15],"identifyexampl":1,"identity_data":14,"identity_hash":10,"ie":14,"if00":14,"ifac":[1,3,7,9,13,14],"ifac_s":7,"ifconf":1,"ifconfig":14,"ignor":[4,7,9,10,12,13,14],"ignored_devic":7,"illus":6,"illustr":[1,7,13],"imag":16,"imagin":[0,9,16],"immedi":[0,4,7,14,16],"immens":16,"immort":16,"immun":0,"immut":[0,16],"impact":[7,9,10,13],"impati":16,"imperson":9,"implement":[0,1,4,6,7,9,10,11,12,13,16],"impli":8,"implic":[6,7,9],"implicit":[9,10,13],"implicitli":14,"import":[0,1,3,5,7,9,10,12,13,14],"importantli":[0,3,16],"importlib":1,"imposs":[13,16],"impract":14,"improv":[3,6,7,11,12,16],"in_fram":1,"in_wait":1,"inactive_for":10,"inadvert":14,"inbound":[1,7,10],"inbox":9,"incent":0,"includ":[0,1,4,5,6,7,8,9,10,11,13,15],"inclus":9,"incom":[1,7,10,14],"incompat":[0,10,13],"incompet":0,"incomplet":9,"inconveni":0,"increas":[4,7,10,14],"incredibli":[0,16],"increment":0,"incur":[0,7],"indefinit":[0,14],"independ":[0,4,6,10,13],"index":[1,3,6],"indic":[1,4,10],"indiffer":16,"indirectli":[8,13],"individu":[0,3,4,7,10,12,13,14,15,16],"industri":0,"inevit":[3,13],"infer":13,"infinit":16,"influenc":0,"influx":[7,11],"influxdb":11,"info":[4,10,13,14,16],"inform":[0,1,3,4,6,7,9,10,11,12,13,14,16],"infrastructur":[4,5,6,7,9,11,13,14],"ingest":16,"ingo":10,"ingress":[1,6],"ingress_control":7,"inhabit":16,"inher":[0,9],"inherit":4,"init":3,"initi":[1,4,7,9,10,13,14,15],"initialis":[1,4,10,14],"input":[1,14],"insert":13,"insid":[4,13,16],"insidi":0,"insight":16,"inspect":[3,4,7,9,13,14],"inspir":16,"instal":[0,1,4,6,7,13,14,15],"instanc":[0,1,6,7,10,11,13,14,16],"instance_control_port":14,"instance_nam":14,"instant":16,"instanti":10,"instantli":14,"instead":[0,1,3,4,7,10,13,14,16],"institut":[0,16],"instruct":[3,4,16],"int":[1,10],"integ":[1,10],"integr":[0,3,4,11,13,14,16],"intellig":[0,8,16],"intend":[3,7,9,13,14],"intens":14,"intent":[9,16],"intention":[11,13],"inter":[3,10,13],"inter_byte_timeout":1,"interact":[0,1,3,6,9,10,13,14,16],"intercept":9,"interchang":[4,7],"interconnect":[3,7,9,13],"interest":[11,13,16],"interfac":[0,4,5,6,9,10],"interface_class":1,"interface_discovery_sourc":[10,14],"interface_en":14,"interfer":[9,14],"intermedi":[9,16],"intermediari":[6,7,13],"intermitt":[0,7,9,16],"intern":[0,1,4,7,10,13,14,16],"internal_1":7,"internet":[0,6,7,9,11,13,14,15,16],"internetwork":3,"interoper":[5,9,11,13,15],"interpret":4,"interregnum":6,"interrupt":[4,7],"interv":[4,7,10,14],"intervent":14,"intiat":1,"intim":16,"introduc":[0,4,13,14,16],"introduct":6,"introductori":6,"intuit":[9,13,15],"invalid":[1,4,7,10],"invari":16,"invers":13,"invert":16,"invest":[0,9],"investig":4,"invis":[3,7],"invit":7,"invok":4,"involv":[0,4,9,12],"io":5,"iodin":11,"ioerror":1,"iot":5,"ip":[3,5,6,7,9,13,14,15],"ipv4":7,"ipv6":[3,7,14],"irc":11,"irrelev":[0,12],"irrespons":16,"is_compress":10,"is_connected_to_shared_inst":1,"is_open":1,"is_path_respons":10,"is_ready_to_send":[1,10],"isdir":1,"isfil":1,"isinst":1,"ism":[5,13],"isn":16,"isol":[3,7,14],"isp":[7,9,16],"issu":[0,4,6,7,9],"its":[0,4,5,7,8,9,10,13,14,16],"itself":[0,4,6,9,11,13,14,16],"iv":[13,15],"j":[6,14],"jail":14,"jan":4,"javascript":11,"job":[0,1],"join":[1,3,9,11,13],"journei":9,"json":[14,16],"judgment":0,"just":[0,1,3,4,5,7,9,11,13,14,15,16],"k":[1,14],"kb":14,"kbp":14,"keep":[1,3,4,9,10,13,14,15,16],"keepal":[10,13],"keepalive_timeout_factor":10,"kei":[0,1,4,6,7,9,10,14,15,16],"kept":[7,9,10,13],"kernel":[0,7,14,15],"keyboardinterrupt":1,"keyerror":10,"keypad":11,"keypair":[9,13],"keyr":16,"keyserv":4,"keyset":[13,14,15],"keysiz":10,"keystor":9,"keyword":4,"khz":7,"ki":1,"kill":[10,13,16],"kilomet":0,"kind":[0,5,7,8,9,11,13,16],"kiss":[5,6,11,14,15],"kiss_fram":7,"kissinterfac":[7,14],"knock":16,"know":[0,1,3,4,5,7,9,10,13,14,16],"knowledg":[9,13],"known":[1,7,10,13,14,15,16],"ko":12,"krypton":1,"l":[4,7,14],"la":14,"label":0,"labor":16,"lack":[0,13],"laid":13,"lake":0,"lan":7,"landlord":16,"languag":[0,4,8,11],"lantern":16,"laptop":[9,16],"larg":[1,5,7,9,10,13,14,15,16],"larger":[9,13,14],"laser":7,"last":[1,4,7,10,14,16],"last_read_m":1,"last_unit":1,"lat":7,"latenc":[3,9,13,15,16],"later":[1,3,4,7,11,14],"latest":[0,1,3,4,7,10,14],"latest_buff":1,"latest_client_link":1,"latitud":7,"laucnh":3,"launch":[11,14],"law":16,"layer":[0,5,7,9,10,11,13,14,15,16],"lcd":11,"lead":[3,13,16],"leak":3,"learn":[1,3,8,9,12,13,16],"leas":16,"leash":16,"least":[3,4,5,7,9,13,14,15],"leav":[0,9,11,13,16],"ledger":[13,16],"leech":0,"left":[0,7,10,13,14],"legaci":[9,16],"legal":[0,7,16],"legisl":7,"legitim":[3,9,14],"len":[1,16],"length":[1,4,7,10,13],"less":[1,3,5,7,10,13,15,16],"let":[0,1,3,4,7,9,11,13,14,16],"level":[0,4,5,7,9,13,14],"lever":16,"li":[0,16],"liabil":8,"liabl":8,"liber":[5,6],"liberapai":12,"libffi":3,"librari":[0,3,11,16],"licens":[6,13,15,16],"lie":16,"life":[0,16],"lifelin":16,"lifespan":0,"lift":[10,14,16],"light":[0,4,14,16],"lightweight":15,"like":[0,1,3,4,5,7,9,10,11,13,14,15,16],"likewis":4,"limit":[1,3,4,5,6,8,9,11,13],"line":[0,1,3,6,7,11,13,14,15,16],"linger":14,"link":[0,3,4,5,6,7,9,10,11,14,15,16],"link_clos":1,"link_establish":1,"link_id":[1,10],"link_mtu_discoveri":10,"linkexampl":1,"linux":[0,3,4,5,7,11,13],"liquid":16,"list":[0,1,3,4,5,6,7,10,11,13,15,16],"list_deliv":1,"list_fil":1,"list_filt":14,"list_packet":1,"list_receipt":1,"list_timeout":1,"listdir":1,"listen":[0,1,3,4,6,11,13,14,16],"listen_ip":7,"listen_on":[3,7],"listen_port":7,"liter":14,"litter":16,"littl":[5,11,13],"live":[0,3,10,11,16],"lki":13,"lkr":13,"ll":[1,15,16],"llm":11,"ln":14,"load":[1,3,4,5,7,10,14,15,16],"load_private_kei":10,"load_public_kei":10,"local":[0,1,3,4,6,7,9,10,11,13,15,16],"locat":[3,6,7,9,13,14,16],"location_cmd":7,"lock":16,"log":[0,1,3,4,7,14,16],"log_crit":1,"log_error":1,"log_info":1,"log_verbos":1,"logdest":10,"logfil":14,"logic":[13,16],"login":14,"loginctl":14,"loglevel":[1,10,14],"lon":7,"long":[1,3,4,5,6,7,9,10,13,14,16],"longer":[1,3,7,13,14,16],"longest":7,"longitud":7,"look":[1,3,4,7,9,11,13,14,16],"loop":1,"lora":[0,3,5,6,9,11,13,15,16],"lorawan":[5,13],"lose":0,"loss":[0,7,9,13],"lost":16,"lot":[9,13,16],"loudest":16,"low":[0,3,4,5,7,9,11,13,15,16],"lower":[1,3,7,14],"lowest":[0,10],"lowli":16,"ltu":5,"lunar":6,"lxmf":[4,6,7,9,10,14],"lxmfy":6,"lxst":6,"m":[1,3,4,13,14],"mac":[7,13],"machin":[0,3,8,13,14,16],"machineri":11,"maco":[6,11],"made":[3,4,7,10,13,16],"mai":[0,3,4,7,9,10,11,13,14,16],"mailbox":11,"mailmap":4,"main":[1,4],"maintain":[0,3,4,9,11,13,14,15],"mainten":[3,9,13,16],"major":4,"make":[0,1,3,4,5,7,9,11,12,13,14,15,16],"malici":[0,3,4,9,13,14],"malinform":12,"manag":[0,3,6,9,10,11,13,15,16],"mani":[1,3,4,5,7,9,10,11,13,14,15,16],"manifest":[0,4],"manipul":[13,15,16],"manjaro":3,"manner":[4,9,11],"manual":[0,1,3,7,9,10,13,14,15,16],"manufactur":[5,7],"map":[7,11,13,14,16],"mark":[3,4,7,8,10,13,15,16],"markdown":4,"market":[0,16],"markqvist":[1,12],"markup":[4,11],"mask":0,"mass":16,"massiv":7,"master":[1,4,10,16],"match":[0,1,4,7,13,14,16],"math":16,"mathemat":16,"matter":[0,3,7,9,16],"matur":14,"max":14,"max_request_s":10,"max_response_s":10,"maximum":[1,7,10,13,14],"mayb":16,"mb":4,"mbp":14,"md":4,"mdu":[1,10],"me":[7,16],"mean":[0,3,4,5,7,9,10,13,14,16],"meaning":3,"meaningless":0,"meantim":10,"measur":[0,9,13,16],"mechan":[0,3,4,6,7,9,14,15],"media":[4,16],"mediat":0,"mediev":16,"medium":[0,1,5,6,7,9,10,11,13,15],"meet":[0,16],"megaphon":16,"member":[3,13],"memori":[3,9,13],"men":0,"mental":16,"mention":[7,13],"menu":1,"menu_mod":1,"merchant":8,"mere":[0,16],"merg":[0,8,14],"merit":6,"mesh":[3,7,9,13,14,15,16],"meshchat":11,"meshchatx":6,"messag":[1,3,4,9,10,11,13,14,16],"message_class":10,"messagebas":[1,6,10],"messagecallbacktyp":10,"messeng":[9,13],"met":[0,3,16],"meta":4,"metadata":[0,3,4,7,13,14,16],"metaphor":16,"metavar":1,"meter":7,"meth":1,"method":[1,3,6,7,10,13],"methodologi":[13,14],"metric":[0,11],"mevpekyafshak5wr":7,"mhz":[7,13],"mi":1,"microcontrol":13,"micromanag":16,"micron":[4,6],"microwav":9,"middl":0,"middlemen":0,"might":[0,3,4,7,9,13,14,16],"migrat":0,"mikrotik":5,"millimet":5,"million":16,"millisecond":[1,9,14,16],"mind":[0,9,16],"mindset":16,"mine":16,"miner":16,"minim":[0,5,6,7,13],"minimalsampl":1,"minimum":[1,3,7,10,13,14,16],"minimum_bitr":10,"miniscul":16,"minor":4,"minut":[1,3,4,7,13,16],"mirror":[0,6,9,14],"mirror_interv":4,"misconfigur":3,"mislead":[3,16],"miss":[1,3,4],"missil":16,"mistak":3,"misunderstand":12,"mitig":9,"mix":[6,7,9,14],"mixtur":15,"mobil":[7,9,13],"mode":[0,1,3,4,5,6,9,10,11,13,14,15,16],"model":[0,8,9,14,16],"modem":[6,7,9,10,11,13,15,16],"modem73":11,"moder":7,"modern":[3,5,11,16],"modif":[0,4],"modifi":[0,4,7,8,9,13,14],"modul":[1,3,4,5,6,7,9,13,14,15],"modular":11,"moment":[13,16],"momentarili":7,"mon":4,"monero":12,"monet":0,"monitor":[3,7,11,13,14],"monolith":0,"monopol":0,"moon":1,"moral":16,"more":[0,1,3,4,5,7,9,10,11,12,13,14,15,16],"moscow":13,"most":[0,3,5,7,9,10,11,13,14,16],"mostli":[7,9,13],"motiv":6,"mountain":16,"move":[4,7,9,13,14,16],"msgpack":4,"msgtype":[1,10],"mtu":[1,7,10,13,15],"mu":4,"much":[3,7,9,11,13,14,15,16],"multi":[0,6,9,11,13,14,15],"multicast":7,"multicast_address_typ":7,"multilater":13,"multipl":[0,1,4,7,9,11,13,14],"multiplex":[1,14],"multipoint":13,"multitud":3,"music":0,"must":[0,1,3,4,7,9,10,13,14,16],"mutual":16,"mw":7,"my":[4,7,13,16],"my_fil":14,"my_ident":14,"my_network":[13,14],"my_network_ident":7,"my_nod":4,"myapp":4,"mycal":7,"myfork":4,"myfriend":16,"mymirror":4,"myrepo":4,"myriad":13,"mysteri":16,"n":[1,4,13,14],"name":[1,3,4,6,7,9,10],"namespac":1,"nano":4,"narg":1,"nat":[3,7],"nation":0,"nativ":[1,9],"natur":[0,7],"navig":[0,4],"nearbi":[7,9],"nearest":7,"nears":13,"neat":9,"neccessari":7,"necesarri":7,"necess":0,"necessari":[0,4,5,7,9,10,13,14],"necessarili":13,"need":[0,1,3,4,5,6,7,9,10,11,12,13,14,15,16],"needless":7,"neg":[3,7],"neglig":[13,16],"negoti":[0,16],"neighbor":16,"neither":[10,13],"neon":1,"neopixel":14,"nerd":4,"net":7,"netcat":7,"network":[0,1,5,7,10,14,15,16],"network_ident":[7,13,14],"network_nam":[3,7],"neutral":[9,16],"never":[0,7,9,10,13,16],"new":[0,1,3,4,6,9,10,13,14,16],"new_id":14,"new_ident":14,"newer":[10,13],"newest":13,"newli":[7,10,13],"newlin":[7,14],"next":[0,3,4,7,10,13,16],"next_hop":10,"next_hop_interfac":10,"nice":16,"nicknam":13,"no1cll":7,"no_data_for":10,"no_inbound_for":10,"no_outbound_for":10,"noauth":14,"nobl":1,"noble_ga":1,"noble_gas":1,"nobodi":4,"nocheck":14,"node":[0,3,6,7,14,15],"node_nam":4,"noid":14,"nois":[0,7,10,12,16],"noisi":16,"nomad":[0,6],"nomadnet":[4,11],"nomadnetwork":11,"non":[3,7,10,11,13,16],"none":[1,3,4,7,10,13,14],"noninfring":8,"nor":[3,16],"normal":[0,1,3,4,7,10,13,14],"nostalgia":0,"notabl":11,"notar":4,"notat":[13,14],"note":[0,1,4,5,6,7,10,13,14],"noth":[4,5,9,15,16],"notic":[4,7,8,13,14],"notif":[0,1,10],"now":[1,3,4,13,14,16],"np":14,"nrf52":5,"nt":1,"null":4,"num":1,"number":[1,3,4,7,9,10,11,13,14,16],"nurtur":0,"o":[1,3,4,7,13,14,15],"obj":4,"object":[1,4,10,16],"obscur":[0,3],"observ":[0,9,16],"obsolet":16,"obstacl":16,"obtain":[0,3,5,6,8,10,13],"obvious":13,"occupi":16,"occur":[1,7,14,15],"ocean":16,"ocur":10,"odd":1,"ofdm":11,"off":[3,7,9,11,13,14,15,16],"offer":[0,3,6,7,9,10,11,13,14,16],"offic":9,"offlin":[0,1,3,6,9,11],"often":[0,3,7,9,13,14,16],"oganesson":1,"old":[0,1,3,5,12,13,16],"older":14,"omit":10,"on_interfac":10,"onc":[1,3,4,5,7,10,13,14,15,16],"one":[0,1,3,4,5,7,9,10,11,13,14,15,16],"ones":[3,7,9,14],"oneself":13,"ongo":11,"onli":[0,1,3,4,5,7,9,10,13,14,15,16],"onlin":[1,10,14,16],"onto":[3,13,16],"ontolog":0,"opaqu":9,"open":[0,1,3,4,5,6,7,9,10,11,12,13,14,15],"open_port":1,"openmodem":[7,15],"openssl":[3,13],"openwrt":6,"oper":[0,3,4,5,7,9,10,13,14,15,16],"opinion":[0,12],"opkg":3,"opportun":3,"opportunist":9,"oppos":4,"opposit":[1,7],"oppress":16,"opt":13,"optic":[5,15,16],"optim":[0,3,4,9,16],"option":[0,1,3,4,5,6,9,10,11,13,14,16],"ord":1,"order":[0,1,7,10,14],"organ":[0,3,4,9,13,14,16],"organis":[7,12],"organiz":0,"orient":13,"origin":[1,4,6,9,11,13,16],"orthogon":0,"os":3,"other":[0,1,3,4,5,7,8,9,10,11,13,14,16],"otherwis":[1,4,7,8,10],"our":[1,7,13,16],"ourselv":9,"out":[1,5,7,8,10,11,13,14,16],"outag":0,"outbound":[7,10,13],"outgo":[1,7,10,13,14],"outlast":0,"outlin":[3,5,13],"output":[0,4,7,14],"outsid":[10,15,16],"over":[1,5,6,7,9,10,11,12,13,14,15,16],"overal":[13,14],"overcom":13,"overhead":[3,5,7,13,16],"overlai":3,"overli":12,"overlord":16,"overrid":[1,4],"oversight":13,"overview":[4,6,7],"overwhelm":[0,7,9,10],"overwrit":14,"own":[0,1,3,4,9,10,13,14,15,16],"owner":[1,16],"ownership":[0,16],"p":[1,4,14],"pace":0,"pack":[1,10],"packag":[0,1,3,4,7,11,13],"packb":1,"packed_s":1,"packet":[0,1,3,6,7,9,10,11,14,15,16],"packet_callback":1,"packet_deliv":1,"packet_hash":1,"packet_receipt":[1,10],"packet_timed_out":1,"packetreceipt":[1,6,10],"pad":[13,15],"page":[0,6,13,14,16],"page_cont":4,"pagin":4,"paid":0,"pair":[7,10,13,14],"pamac":3,"panic":[1,14,16],"panic_on_interface_error":[1,14],"panopticon":16,"paper":11,"par":[1,3],"paradox":16,"parallel":3,"paralysi":16,"param":1,"paramet":[1,5,6,10,13,14],"paranoia":16,"parasit":16,"pariti":[1,7,14,15],"parity_even":1,"parity_non":1,"parity_odd":1,"pars":[1,4],"parse_arg":1,"parser":[1,4,6],"part":[0,1,3,4,7,9,10,11,13,14,16],"parti":[0,4],"partial":4,"particip":[0,3,6,7,9,13,14,16],"particular":[0,1,5,7,8,13,14],"particularli":[0,4,7,14],"partner":16,"pass":[1,4,5,7,9,10,13,14,16],"passphras":[3,7,9,13],"passport":13,"past":14,"patch":[0,4,16],"path":[0,1,3,4,5,6,9,10,13,14,16],"path_respons":10,"pathfinder_m":10,"patient":16,"pattern":[0,4,5,6,9,13],"payload":[1,4,7,10,13,14],"pdf":6,"peac":16,"peach":1,"peak":4,"peer":[0,1,3,4,7,10,11,13,14,16],"penalti":7,"pend":[1,13],"peopl":[0,3,11,13,16],"per":[0,4,7,9,10,11,13,14,15,16],"percent":[1,7],"percentag":10,"perfectli":[0,3],"perform":[0,1,3,4,7,9,10,11,13,14,16],"perhap":[3,16],"period":[1,4,7,10,13,14],"peripher":11,"perm":4,"perman":[3,7,14],"permiss":[0,6,7,8,14,16],"permissionless":[0,13,14],"permit":8,"perpetu":16,"persecut":13,"persist":[0,7,14,16],"person":[6,7,8,9,12,13],"personag":0,"perspect":[0,7,9,10,13,15],"pet":1,"petit":16,"philosophi":[0,12,13,15,16],"phone":[3,6,9,16],"phonebook":11,"photo":16,"phy":14,"physic":[0,1,3,4,5,6,7,9,10,11,13,14,15],"pi":[0,1,6,9,13,14,15,16],"pick":13,"piec":13,"pillar":16,"ping":[14,16],"pip":[1,3,4,5,7,14],"pip3":3,"pipe":[6,11,14,15,16],"pipeinterfac":[5,7,11],"pipx":3,"pitfal":13,"pkcs7":[13,15],"pkg":3,"place":[1,3,4,7,9,13,14,16],"plaform":5,"plain":[1,5,7,10,13,16],"plain_mdu":10,"plaintext":[1,10,16],"plan":[9,13,16],"planet":[0,16],"planetari":[15,16],"platform":[1,4,5,6,11,13,14,16],"pleas":[1,3,7,10,14,16],"plenti":[9,13],"plu":10,"plug":[14,16],"plugin":[11,16],"pmr":13,"poetri":16,"point":[0,3,4,5,7,9,11,12,13,14,16],"pointer":3,"polici":[0,14,16],"polit":16,"pomelo":1,"popul":10,"popular":15,"port":[1,3,5,6,7,9,13,15,16],"port0":14,"portabl":[0,6,7,9,13],"portion":8,"pose":[3,13],"posit":[1,4,7,14],"posix":3,"possess":[7,13,16],"possibl":[0,3,4,5,7,9,10,11,13,14,15],"possibli":[3,13],"post":[1,6],"postfix":14,"potenti":[0,1,3,4,7,12,13,14,15,16],"power":[0,3,5,6,7,9,11,13,14,15],"powershel":3,"ppp":1,"pr":14,"practic":[0,4,9,13,15,16],"pre":[3,9,10,13],"preambl":[7,14],"preced":[1,4],"preciou":9,"precis":0,"precompil":3,"predatori":16,"predic":0,"predict":13,"prefer":[3,4,12,13],"prefer_ipv6":7,"premis":[9,16],"prepar":[1,13],"prerequisit":[6,10],"prescrib":0,"presenc":[0,6,7,10],"present":[0,7,9,11,13,14,16],"preserv":[0,3,6,10],"preshar":13,"press":1,"pressur":0,"pretend":[11,13],"prettyhexrep":1,"prevent":[0,4,7,9,14,16],"preview":4,"previou":1,"previous":[7,10,13],"price":16,"primari":[0,13,16],"primarili":[7,9,11],"primarlii":3,"primit":[3,4,6],"principl":[0,6,9,13,15],"print":[1,4,7,14],"print_filelist":1,"print_help":1,"print_menu":1,"priorit":[7,9,13,16],"prioriti":[7,13],"prioritis":[6,7,9,10],"privaci":[3,7,11,16],"privat":[0,3,4,7,9,10,11,12,13,14,15,16],"private_ret":3,"privileg":[0,14,16],"probabl":[1,3,4,9,13,14,15],"probe":14,"problem":[0,3,4,13,14,16],"problemat":4,"proc":14,"procedur":[3,4,10,13],"process":[0,1,3,4,5,7,9,10,13,14,16],"process_incom":1,"process_outgo":1,"produc":0,"product":[0,14,16],"profil":16,"profit":16,"profound":[9,16],"profoundli":16,"program":[1,4,5,6,7,10,13,15],"program_setup":1,"programm":13,"programmat":[0,13],"progress":[1,4,10,14,15],"progress_callback":10,"project":[0,4,11,12,16],"promis":3,"prompt":[1,3],"proof":[0,1,4,7,9,10,13,14,16],"proof_packet":1,"proof_requested_callback":10,"proof_strategi":10,"propag":[6,7,9,10,11,14,16],"proper":3,"properli":3,"properti":[0,1,9,10],"proport":13,"propos":6,"prospect":0,"protect":[0,3,14,16],"protocol":[3,4,5,6,7,9,15],"prove":[1,4,9,13,16],"prove_al":[1,10],"prove_app":10,"prove_non":10,"proven":[0,4,10,13],"provid":[0,1,3,4,5,6,7,8,9,10,11,13,14,15,16],"provis":[5,14],"prv_byte":10,"prx":14,"pseudo":14,"psycholog":[0,16],"ptx":14,"pub_byt":10,"pub_to_fil":10,"public":[1,4,6,7,9,10,12,14,15],"public_inform":1,"publicli":[3,7,13,14],"publish":[0,3,4,6,7,8,10,13],"publish_blackhol":14,"publish_blackhole_en":10,"publish_ifac":7,"pull":[0,4],"puppet":16,"purchas":[3,13,15],"pure":[6,13],"purg":10,"purpos":[0,3,4,5,7,8,9,10,11,13,14,16],"purposefulli":8,"pursu":0,"push":[0,4,11,16],"put":[0,1,5,7,14],"pwd":4,"py":[1,4,13,14],"py3":[3,4],"pyca":[3,13],"pygment":4,"pyseri":[1,3],"python":[0,1,4,6,7,10,13,14,15,16],"python3":[1,3,5],"q":[1,4,14],"qlen_in_announc":7,"qlen_in_data":7,"qlen_in_il":7,"qlen_in_pr":7,"qr":[9,11],"qualiti":[0,10,14,16],"quantiti":0,"queri":[1,3,4,10,14,16],"question":[3,5,7],"queu":[10,14],"queue":[6,13,14],"quick":14,"quickli":[7,11,12,13,15],"quiet":[4,7,14,16],"quinc":1,"quirk":3,"quit":[1,3],"quot":4,"qvist":[8,15],"r":[1,4,7,13,14],"radic":16,"radio":[0,6,7,9,10,11,13,14,15,16],"radon":1,"rais":[0,1,10],"rak":5,"ram":[3,7],"randint":1,"random":[0,1,10,12,13],"random_text_gener":1,"randomis":13,"randomli":[1,13],"rang":[0,1,3,4,5,7,9,13,14,15,16],"rapidli":7,"rare":[3,7],"raspberri":[0,6,9,13,14,15],"rasperri":3,"ratchet":[10,13],"ratchet_count":10,"ratchet_expiri":10,"ratchet_id_receiv":10,"ratchet_interv":10,"ratchets":10,"ratchets_path":10,"rate":[1,3,6,10,11,14],"rather":[0,3,10,11,14,16],"ratio":[0,10],"raw":[1,4,5,10],"rawchannelread":[6,10],"rawchannelwrit":[6,10],"rawiobas":10,"rawmu":4,"rb":1,"rbrowser":6,"re":[0,1,7,9,10,13,14,16],"reach":[0,3,6,7,9,10,14,16],"reachabl":[0,1,3,7,9,10,11,13,14],"reachable_on":7,"reactiv":0,"read":[0,1,3,4,7,9,10,13,14,15,16],"read_loop":1,"readabl":[0,1,7,10,13,14,16],"reader":[1,10],"readi":[1,3,5,7,10,15,16],"readili":15,"readm":4,"readwrit":4,"ready_byt":[1,10],"ready_callback":10,"real":[0,3,5,7,9,11,14,15,16],"realiti":[0,3,12,16],"realiz":16,"realli":[7,10,14,16],"realm":16,"reappear":7,"reason":[3,7,10,13,14],"reassembl":13,"reboot":16,"rebroadcast":9,"rebuilt":16,"recal":[1,4,10,14],"recall_app_data":10,"recap":13,"receipt":[1,9,10,13],"receiv":[1,3,4,7,9,10,12,13,14,16],"receive_path_respons":10,"receive_stream_id":10,"received_announc":[1,10],"recent":[10,13],"recept":10,"reception_rssi":1,"reception_snr":1,"reception_stat":1,"recip":3,"recipi":[0,4,13,16],"reclaim":16,"recogn":[13,16],"recognis":14,"recognit":[0,16],"recombin":0,"recommend":[0,1,3,7,13],"recondit":14,"reconnect":[1,9,16],"reconnect_port":1,"reconstruct":13,"record":[0,3,4,13],"record_stat":4,"recov":0,"recoveri":7,"recreat":13,"recurs":[7,10,13],"recursive_pr":7,"reduc":[7,14],"redund":[3,9],"reestablish":0,"ref":4,"refactor":4,"refer":[0,1,3,4,6,7,11,14,16],"refin":12,"reflect":0,"refresh":14,"refus":9,"regain":[0,3],"regard":[0,13],"regardless":[0,4,7],"region":7,"regist":[1,4,10,14],"register_announce_handl":[1,10],"register_message_typ":[1,10],"register_request_handl":[1,10],"registrar":16,"registri":[0,16],"regul":7,"regular":14,"regulatori":16,"regurgit":16,"reintroduc":0,"reject":[4,16],"rel":[4,5,7,9,13],"relai":[3,6],"relat":[3,4],"relationship":[0,9,13,14,16],"releas":[0,3,6,7,13,14,16],"relev":[1,3,4,5,7,10,13,14,16],"reli":[3,4,7,9,12,13,14,16],"reliabl":[3,5,7,9,10,13,15,16],"relianc":[3,16],"relief":9,"reload":14,"rem":1,"remain":[0,4,7,9,10,11,13,16],"rememb":[7,9,10,13],"remot":[1,6,10,13],"remote_ident":[1,4,10],"remote_identifi":1,"remote_management_allow":14,"remote_management_en":10,"remote_nod":4,"remote_p":1,"remotesensor":13,"remov":[0,4,10,14,16],"remove_message_handl":10,"remove_ready_callback":10,"render":[4,11,16],"rent":16,"reopen":4,"repeatedli":[0,7],"replac":[0,1,3,9,10,11,13,14,16],"repli":[1,14],"replic":[0,5,13],"reply_data":1,"reply_messag":1,"reply_text":1,"repo":[4,14],"repo_nam":4,"report":[7,10,12,14],"repositori":[0,3,6,13,14,16],"repres":[0,9,13,16],"represent":[1,10,16],"repudi":4,"repurpos":3,"reput":[13,14],"request":[0,4,6,9,10,13,14,15,16],"request_destin":1,"request_fail":1,"request_id":[1,10],"request_packet":1,"request_path":[1,10],"request_receipt":[1,10],"request_receiv":1,"requested_at":[1,10],"requestexampl":1,"requestor":7,"requestreceipt":[6,10],"requir":[0,1,3,4,7,9,10,11,13,14,15,16],"require_shared_inst":10,"required_discovery_valu":[10,14],"rerout":16,"research":0,"resend":10,"reserv":[1,9,10,16],"reset":4,"reshap":0,"resid":[7,16],"resili":[0,3,9,11,14,15,16],"resist":9,"resiz":14,"resolut":[3,4,7,13],"resolv":[4,6,7,9,13,14],"resourc":[1,3,6,7,9,10,12,14,16],"resource_callback":10,"resource_sending_conclud":1,"resource_strategi":10,"respawn":7,"respawn_delai":7,"respawn_interv":7,"respect":[0,4,7,9,15,16],"respond":[0,1,9,10,14],"respond_to_prob":14,"respons":[0,6,7,10,13,15,16],"response_callback":[1,10],"response_gener":[1,10],"rest":[9,15,16],"restart":[7,14],"restartsec":14,"restor":[3,6,7,16],"restrict":[4,7,8,9,14,16],"resubmit":4,"result":[0,1,3,7,13,14],"ret":[6,13],"retain":[0,4,7,10],"retained_ratchet":10,"retibb":6,"reticulum":[0,1,7,9,10],"retipedia":6,"retransmiss":[9,13],"retransmit":[7,13],"retri":[1,4,10,13],"retriev":[0,4,10,14],"return":[0,1,7,10,14,16],"reveal":[3,10,13,15],"revers":14,"review":[0,13],"revis":14,"revok":[4,16],"revolut":16,"revolutionari":0,"rfe":14,"rich":11,"ridicul":13,"right":[0,3,4,7,8,16],"rigid":16,"rington":11,"rippl":16,"risc":6,"risk":[4,13],"riski":16,"rm":4,"rmap":3,"rn":[0,1,3,4,5,6,10,13,14,16],"rncp":6,"rngc":4,"rngit":[0,6],"rngit_config":4,"rnid":[4,6,13],"rnmon":6,"rnode":[3,6,13,14,15],"rnodeconf":[5,6],"rnodef3b9":7,"rnodeinterfac":[3,5,7,14],"rnodemultiinterfac":7,"rnpath":[3,6,7],"rnphone":11,"rnprobe":[3,6],"rns_bin_dir":14,"rns_config":4,"rns_remot":4,"rnsconfig":[4,14],"rnsd":[3,6],"rnsh":[6,11],"rnspure":[3,13],"rnstatu":[3,6,7,13],"rnstransport":[7,14],"rnx":6,"road":[6,16],"roadmap":[12,16],"roam":[6,7,9],"robot":13,"robust":[3,7,16],"role":9,"roll":7,"rom":14,"room":[11,16],"root":[4,13],"rotat":[7,10,13,14],"round":[1,10,14],"rout":[3,5,7,9,10,11,13,14,15,16],"router":[3,7,9,14,16],"rpc":14,"rpc_kei":14,"rprogress":1,"rrc":6,"rrcd":11,"rsg":[0,4],"rsm":[0,4],"rssi":[1,10,14],"rtsct":1,"rtt":[1,10,13],"rttstring":1,"rubber":16,"rule":[0,3,4,6,7,9,14,16],"run":[0,1,3,4,5,7,9,10,11,13,14,15,16],"runtim":[1,13],"rust":3,"rvp":4,"rw":4,"rx":[7,14],"rxb":1,"sa":11,"safe":[4,13,14,16],"safeguard":16,"safeti":0,"sai":[0,16],"said":[4,13],"sake":0,"same":[0,1,3,4,5,7,9,10,11,13,14,16],"sand":16,"satellit":9,"satisfi":13,"satur":0,"save":[4,10,13,14],"save_error":1,"saved_filenam":1,"saw":11,"scalabl":[14,15],"scale":[13,15,16],"scan":[3,7],"scarc":16,"scarciti":6,"scatter":16,"scenario":[3,7,13],"schedul":[4,10],"scheme":[0,4,5,7,14],"scope":[4,7],"scrape":16,"scratch":[5,16],"screen":1,"script":[0,3,4,5,7,14],"scrutini":13,"sd":0,"se":4,"sea":7,"seamless":[7,13],"seamlessli":[7,9],"search":[6,10,11],"second":[1,7,9,10,11,13,14,15,16],"secreci":[7,10,11,13,15],"secret":[9,13],"section":[3,4,5,7,9,11,13,14],"secur":[0,3,4,6,9,11,13,14,15,16],"sed":4,"see":[1,3,4,7,9,10,13,14,15,16],"seek":[0,13,16],"seen":[7,13,16],"segment":[1,3,7,9,10,13,14,15],"select":[1,3,4,7,16],"self":[0,1,3,4,13,15,16],"sell":8,"semi":[4,14],"semtech":5,"send":[1,4,7,9,10,13,14,16],"send_stream_id":10,"sender":[1,3,9,13,14],"sens":[0,9,16],"sensibl":[3,5,7],"sensit":16,"sensor":[9,13],"sent":[1,3,9,10,13,14,16],"sentiment":13,"separ":[0,1,7,9,11,13,14],"seq":4,"sequenc":[1,4,10,13,14,15],"sequenti":[4,15],"serfdom":16,"seri":5,"serial":[1,3,6,9,13,15,16],"serialinterfac":[5,7],"seriou":0,"serv":[0,1,5,6,7,9,11,12,13,14,16],"serve_nomadnet":4,"serve_path":1,"server":[0,1,3,4,5,6,9,10,11,13,14,16],"server_buffer_readi":1,"server_callback":1,"server_client_connect":1,"server_destin":1,"server_fil":1,"server_ident":1,"server_link":1,"server_loop":1,"server_message_receiv":1,"server_packet_receiv":1,"servic":[0,3,4,6,7,9,11,13,16],"session":[3,11,13,14],"set":[0,1,3,4,5,7,9,10,11,13,14,15,16],"set_default_app_data":10,"set_delivery_callback":[1,10],"set_link_closed_callback":[1,10],"set_link_established_callback":[1,10],"set_max_request_s":10,"set_packet_callback":[1,10],"set_proof_requested_callback":10,"set_proof_strategi":[1,10],"set_ratchet_interv":10,"set_remote_identified_callback":[1,10],"set_resource_callback":10,"set_resource_concluded_callback":[1,10],"set_resource_started_callback":[1,10],"set_resource_strategi":[1,10],"set_retained_ratchet":10,"set_timeout":[1,10],"set_timeout_callback":[1,10],"setup":[1,3,4,6,7,14],"sever":[3,4,9,10,14],"sf":14,"sh":7,"sha":[9,10,13],"sha256":[4,13,15],"shall":[8,13],"shape":[9,16],"share":[0,1,3,9,10,11,13,14,16],"share_inst":14,"shared_instance_port":14,"shared_instance_typ":[10,14],"shelf":[13,15],"shell":[0,3,4,6,14,16],"shelter":0,"shift":[0,16],"shim":4,"shine":16,"ship":[13,16],"shop":[1,16],"short":[5,6,7,13,14],"shorter":7,"shorthand":[7,14],"shortlog":4,"shot":3,"should":[0,1,3,4,7,9,10,13,14,16],"should_ingress_limit":1,"should_quit":1,"should_use_implicit_proof":10,"shout":16,"shove":0,"show":[3,4,14,16],"shown":[0,1,12],"shut":[0,16],"side":[0,7,14,15],"sideband":[3,6,14],"sign":[0,6,7,9,10,13,14,16],"signal":[0,1,7,10,13,14,16],"signatur":[0,6,9,10,13,14,15,16],"signer":4,"signifi":13,"signific":9,"significantli":[7,10],"signingkei":4,"silent":14,"similar":[0,1,3,4,5,7,10,11,14,15],"simpl":[1,3,4,5,10,11,13,14,15,16],"simpler":[4,7,9,15],"simplest":[7,13],"simpli":[0,1,3,4,5,7,9,11,12,13,14,16],"simplic":13,"simplifi":1,"simplyequip":5,"simul":13,"simultan":[3,13],"sinc":[1,3,4,7,9,10,13,16],"singl":[0,1,3,4,7,9,10,13,14,15,16],"singular":13,"sit":[3,16],"site":[0,7,9,16],"situat":[3,4,5,7,9,13,14],"size":[1,3,4,7,10,13,14],"size_str":1,"skill":0,"skip":[1,4],"sky":6,"slap":16,"slave":16,"sleep":[1,3,14],"slice":[1,16],"slightli":[1,3,16],"sloppi":16,"slottim":[7,14],"slow":[1,7,9,11,13,16],"slower":[7,10,13],"slowest":10,"small":[1,3,7,9,10,13,15,16],"smaller":10,"smallest":3,"snippet":14,"snr":[1,10,14],"so":[0,1,3,4,5,7,8,9,10,11,12,13,14,15,16],"social":[0,3,16],"societi":16,"socket":[7,14,15,16],"soft":16,"softwar":[0,3,4,5,7,8,11,13,14,16],"solar":16,"sole":7,"solid":12,"solo":0,"solut":[0,13,14],"solv":[0,13,16],"some":[0,1,3,5,7,9,10,11,13,14,16],"some_program":4,"some_program_1":4,"some_remot":4,"someon":[0,3,4,7,14,16],"someth":[0,4,7,9,13,16],"somethign":1,"sometim":[5,7,11,16],"somewhat":3,"somewher":16,"soon":[4,10,14],"sort":[7,13,14],"soul":16,"sound":16,"soundmodem":7,"sourc":[0,1,3,4,5,6,9,10,13,15,16],"source_":4,"sovereign":[0,3,13,16],"sovereignli":16,"sovereignti":[6,15],"space":[0,1,3,5,9,13,15,16],"spam":[3,7,13,14],"spammi":14,"span":[7,9,13],"spawn":7,"spe":7,"speak":[0,12,16],"spec":13,"special":[11,13,14],"specif":[0,1,4,5,6,7,9,10,14,15,16],"specifi":[0,1,3,4,5,7,9,10,13,14],"spectrum":[7,13,16],"speed":[1,7,10,13,14,16],"sphere":16,"spinner":16,"spirit":11,"split":1,"sponsor":12,"spoof":[4,16],"spread":[7,14],"spreadingfactor":7,"squelch":7,"ssh":[4,11,14],"ssid":7,"ssl":16,"stabil":[9,16],"stabl":[3,7,9,13,15],"stack":[1,3,9,10,11,13,14,15,16],"stage":13,"stai":[1,7,13,14,16],"stake":0,"stale":[9,10],"stale_grac":10,"stale_tim":10,"stamp":[7,10,14],"stanc":[0,16],"stand":[0,16],"standalon":[6,11],"standard":[0,4,5,7,11,13,14],"start":[1,4,5,6,7,9,10,11,13,14,16],"startup":[1,3,14],"stat":[4,10,14],"state":[0,1,6,9,16],"static":[3,4,7,10,16],"staticmethod":1,"station":7,"stationari":[9,14,16],"statist":[1,6,7,10,12],"stats_ignore_ident":4,"statu":[1,3,4,6,7,10,11,13,14,16],"stderr":14,"stdin":[7,14],"stdio":15,"stdout":[1,4,7,14],"steel":16,"stem":12,"step":[1,3,4,5,16],"stewardship":16,"still":[0,1,3,4,7,9,13,14,16],"stock":1,"stone":16,"stop":[10,15,16],"stopbit":[1,7,14],"storag":[3,6,7,11,13,14,16],"store":[0,1,4,6,10,11,13,14],"store_tru":1,"storm":16,"str":[1,10],"straightforward":7,"strang":16,"stranger":16,"strangl":16,"strateg":9,"strategi":[0,6,7,10],"stream":[0,1,10,11,13,14,16],"stream_id":[1,10],"street":16,"strength":[10,15,16],"strict":[0,16],"strictli":[7,13],"string":[1,10,16],"stringmessag":1,"strip":[0,4,16],"strong":[3,4,13,16],"stronger":3,"strongli":3,"struct":1,"structur":[0,1,6,9,10,13,15,16],"studi":0,"style":[4,7],"sub":[1,7],"subclass":[1,10],"subcommand":4,"subdirectori":4,"subinterfac":7,"subject":[3,8,14,15,16],"sublicens":8,"submit":0,"subnet":[3,9],"subscrib":[3,14,16],"subsequ":[1,4,13],"subset":7,"subsid":7,"substanti":[0,8],"substrat":[0,16],"subtl":16,"subtli":16,"succe":[3,4,14],"succeed":[1,10],"succesfulli":9,"success":[0,3,4,7,10],"successful":10,"successfulli":[1,10,13],"suddenli":16,"sudo":[3,14],"suffer":9,"suffic":13,"suffici":[3,7,13,14,15],"suffix":1,"suit":[0,3,5,11,13,14,16],"suitabl":[1,3,7,9,13,14,15],"sum":16,"super":1,"supersed":7,"superstructur":0,"suppli":[1,7,10,13,14,15],"supplier":3,"support":[0,1,3,4,6,7,9,10,11,13,14,15],"suprem":0,"sure":[1,3,4,5,7,14],"surfac":16,"surrend":0,"surround":[0,16],"surveil":[0,13,16],"surviv":[3,13,14,16],"suspend":0,"sustain":16,"swim":0,"switch":[5,7,9,13,14,16],"sx1262":5,"sx1268":5,"sx1276":5,"sx1278":5,"sx1280":5,"sy":1,"symlink":14,"symmetr":[10,13],"sync":4,"syncer":4,"synchron":[0,6,11,16],"syntax":6,"synthet":16,"system":[0,1,3,4,5,6,7,8,9,10,11,12,13,15],"systemctl":14,"systemd":14,"t":[0,1,3,4,7,9,10,13,14,16],"tabl":[3,7,9,13,14,16],"tablet":3,"tackl":11,"tag":[4,10],"tail":7,"tailor":13,"take":[0,1,3,4,7,10,11,13,14,15,16],"taken":[1,4,13,14,16],"talk":[11,16],"tamper":[0,4,16],"tangerin":1,"tap":[5,16],"tar":4,"target":[1,3,4,7,11,14,16],"target_hash":10,"target_host":7,"target_port":[7,14],"task":[4,14],"taught":16,"tcp":[3,5,6,9,13,14,15,16],"tcpclientinterfac":[3,5,7],"tcpinterfac":14,"tcpserverinterfac":[3,7],"tdata":1,"teach":[14,16],"teahous":[0,12],"team":4,"teardown":[1,10],"teardown_reason":1,"tech":16,"technic":[0,4],"technician":16,"technolog":0,"technologi":[3,9,16],"teffect":1,"telco":16,"telecom":16,"telemetri":[11,12],"telephon":6,"telephoni":11,"televis":16,"tell":[1,3,7,9,16],"temperatur":13,"templat":6,"temporari":[3,7,14],"temporarili":[7,9],"ten":13,"tenanc":16,"tenant":16,"tend":7,"tenuou":16,"term":[0,3,7,9,13,16],"termin":[1,3,4,10,11,14],"terminologi":[9,13],"termux":3,"terrifi":16,"territori":0,"test":[3,4,11,13,14,16],"testimoni":0,"testnet":14,"tether":16,"text":[1,11,13,14],"textur":16,"tfile":1,"tgz":[4,14],"than":[0,1,3,4,7,9,10,11,12,13,14,15,16],"thank":4,"theatric":0,"thei":[0,1,3,4,7,9,10,11,13,14,16],"them":[0,1,3,4,5,7,9,11,12,13,14,15,16],"theme":4,"themselv":[0,4,7,9,14],"theori":[0,16],"thereaft":13,"therefor":[3,13,15,16],"thi":[0,1,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"thing":[1,3,9,11],"think":[3,5,7,9,12,13,16],"third":[0,4],"those":[0,3,9,13,14,16],"though":[0,3,7,9,13],"thought":16,"thousand":[0,3,7,13,14,16],"thread":[0,1,4],"threat":14,"three":[3,13,16],"threshold":7,"throough":7,"throttl":[7,9],"through":[1,3,4,5,6,7,9,10,11,13,14,15],"throughout":[9,13],"throughput":[0,10,11,13,15],"thrown":[10,16],"thu":[9,10,13],"ti":[1,9,13],"tighten":16,"tightrop":16,"tild":14,"time":[0,1,3,4,5,6,7,9,10,11,12,13,14],"time_since_last":1,"timefram":0,"timeout":[1,10,14,16],"timeoutarg":1,"timer":4,"timescal":0,"timestamp":[1,4,10,13,16],"timestr":1,"tion":7,"titl":4,"tl":16,"tmp":14,"tnc":[5,7,10,11,14,15],"to_fil":10,"todai":[0,13,16],"togeth":[5,9,13,14,16],"toggl":14,"token":[10,13,15],"tokyo":16,"told":16,"toler":7,"tomorrow":16,"too":[1,9,16],"tool":[0,3,4,5,6,7,9,11,13,14,15],"toolkit":[3,9],"top":[0,11,13,14,16],"topic":[3,13],"topograph":7,"topographi":[3,9,13,16],"topologi":[3,7,9,13,15,16],"torn":[10,14],"tort":8,"tortur":16,"torvald":0,"total":[4,10,13,14,15],"total_s":1,"touch":[7,16],"toward":[1,7,13],"tower":16,"toxic":0,"track":[0,4,10,14,16],"track_phy_stat":10,"trade":[9,13],"tradit":[4,9,13,16],"tradition":0,"traffic":[1,3,7,9,10,13,14,16],"train":[8,16],"transceiv":[3,5,7,11,13,15],"transfer":[1,4,10,13,14,15],"transfer_s":1,"transform":15,"transient":16,"transistor":16,"translat":9,"transmiss":[3,7,10,13,16],"transmit":[1,4,7,13,16],"transmitt":16,"transpar":[4,5,7,9,13,14],"transport":[0,1,3,4,6,7,10,11,14,15,16],"transport_en":10,"transport_ident":14,"travel":[0,16],"travers":[0,3,7,10,13,16],"treat":[0,4,9,13,16],"tree":[0,4],"tremend":9,"tri":1,"trigger":7,"trip":[1,10,14],"trivial":[13,15],"troubl":16,"true":[0,1,3,7,10,14,16],"truli":[5,13,16],"truncat":[10,13,14],"truncated_hash":10,"truncated_hashlength":[1,10],"trust":[0,3,4,6,7,9,13,14],"trustless":[6,13,15],"trustworthi":[9,14],"truth":4,"try":[1,4,6,7,9,10,11],"ttime":1,"ttransfer":1,"ttyacm0":7,"ttyusb0":[1,7,14],"ttyusb1":7,"ttyusb2":7,"tun":[5,7],"tun0":7,"tune":6,"tunnel":[3,7,9,13,15,16],"tupl":10,"turn":[0,1,7,14,16],"turnaround":7,"tutori":3,"two":[0,1,4,5,7,9,10,13,14],"tx":[7,14],"txb":1,"txp":14,"txpower":7,"txt":[4,14],"txtail":[7,14],"type":[1,3,6,7,9,10,14],"typeerror":10,"typic":[4,7,9,13],"tyrant":16,"u":[13,14,16],"ubiqu":5,"ubuntu":[6,14],"uci":3,"udp":[6,9,13,14,15],"udpinterfac":7,"uhf":[14,15],"ui":[11,16],"ultim":[3,13,16],"umsgpack":1,"unavail":4,"unblackhol":14,"unblackhole_ident":10,"unblock":14,"unbound":16,"uncar":16,"uncencrypt":1,"uncentraliz":6,"unchang":9,"uncoordin":[3,16],"under":[0,4,7,10,12,13,14,15,16],"underli":[1,7,9,10,13,15],"undermin":16,"underneath":16,"undersea":16,"understand":[0,3,6,7,9,10,14,15,16],"understood":16,"underwai":3,"underwear":16,"unencrypt":[1,10,13],"unequivoc":13,"unexplor":9,"unforeseen":0,"unforg":[9,15],"unfortun":3,"unicod":4,"unicode_icon":4,"unidentifi":1,"unidirect":1,"unifi":[9,13],"uninform":0,"uninterest":1,"uniqu":[1,7,9,10,11,13,14,15,16],"unit":[0,1,3,10,14],"univers":16,"unix":[4,10],"unknown":[1,7,9,10,13,14],"unlearn":16,"unless":[1,3,7,9,10,13],"unlicens":13,"unlik":[0,4,13],"unlock":14,"unmedi":0,"unnecessari":7,"unorganis":9,"unpack":[1,10],"unpackb":1,"unpaid":16,"unplug":[14,16],"unrecover":[1,14],"unreli":7,"unsatur":0,"unset":13,"unsupport":10,"until":[1,3,7,10],"untrust":[4,14],"untrustworthi":16,"unus":14,"unwant":[13,14],"up":[0,1,3,4,5,7,9,10,11,13,14,15,16],"updat":[0,1,3,4,10,13,14,16],"upgrad":[3,10,13],"upkeep":7,"upload":4,"upon":[0,1,7,13],"upset":1,"upstream":[0,4,14],"uptim":16,"urandom":[13,15],"urgenc":0,"urgent":16,"uri":11,"url":[0,4,14,16],"us":[0,1,4,5,6,7,8,9,10,16],"usabl":[4,7,13],"usag":[4,6,7,10,11,12,14],"usb":[0,5,13,14],"useabl":13,"useless":[0,16],"user":[0,1,3,4,7,9,11,13,14,15,16],"user_input":1,"userland":15,"usernam":16,"usernameher":14,"usr":[7,14],"usual":[3,7,9],"utf":1,"util":[1,5,6,7,13,16],"utilis":[1,3,7,10,13,14,15],"ux":11,"v":[4,6,14],"valid":[0,1,3,6,7,9,10,13,14,16],"valu":[0,1,3,4,7,10,13,14,16],"valuabl":[0,4,5,12,16],"valueerror":[1,10],"vanish":16,"vanishingli":16,"var":4,"vari":[3,7,13,14],"variabl":[1,3,4,10],"varieti":[7,11,13,14,15],"variou":[1,3,7,9,10,11,13,14,15],"vast":[0,3,13,16],"vastli":9,"ve":9,"vehicl":7,"veloc":0,"vendor":[1,5,15],"ventur":16,"venu":0,"verbos":[4,10,14],"veri":[0,3,4,5,7,9,10,11,12,13,14,15,16],"verif":[0,6,9,10,11,13,14,16],"verifi":[0,1,3,6,7,9,10,13,14,15,16],"versa":15,"version":[0,1,3,4,13,14,16],"vhf":[13,15],"vi":4,"via":[0,3,4,5,7,9,11,12,13,14,15,16],"viabl":9,"vice":15,"video":16,"view":[0,3,4,7,12,13,14],"viewabl":4,"vim":4,"violat":7,"virtual":[3,5,7,9,13,14,15],"virtuou":16,"visibl":[0,1,4,7],"visual":[4,13,16],"vital":16,"voic":[0,11,12,16],"voicemail":11,"volunt":3,"voluntari":3,"vouch":16,"vpn":[9,16],"vport":7,"vulner":9,"vv":14,"vvv":3,"w":[4,14],"wa":[0,1,4,5,7,9,10,13,14,15,16],"wai":[0,1,4,6,7,9,10,11,13,14,16],"wait":[1,3,7,11,13,14,16],"walk":16,"wall":16,"wander":16,"want":[0,1,3,4,7,9,11,12,13,14,16],"wantedbi":14,"warn":14,"warrant":15,"warranti":8,"wash":16,"wast":[7,9,12,16],"wave":[5,16],"wb":1,"we":[0,1,3,5,7,9,12,13,16],"weaken":13,"weapon":[0,16],"wear":16,"weather":16,"weav":16,"web":[3,11,16],"websit":[3,7,16],"weigh":16,"weight":[0,4,14,16],"welcom":0,"well":[0,4,5,7,9,10,11,12,13,14,15,16],"went":1,"were":[0,1,4,11,16],"what":[0,1,3,4,6,7,9,10,13,14,16],"whatev":[9,10,13],"wheel":[3,4],"when":[0,1,3,4,5,7,9,10,11,13,14,16],"whenev":[1,10,13],"where":[0,3,4,5,6,7,9,10,11,13,14,16],"whereupon":13,"wherev":16,"whether":[1,3,4,7,8,9,10,13,16],"which":[0,1,3,4,7,8,9,10,11,13,14,15,16],"while":[0,1,3,4,5,7,9,10,11,13,14,15,16],"whim":16,"whitelist":13,"whl":[3,4],"who":[0,3,4,7,9,13,14,16],"whole":[14,16],"whom":[8,16],"whose":[14,16],"why":[0,16],"wide":[3,4,5,7,9,11,13,14,15],"wider":[3,7,9,13,14],"wield":0,"wifi":[3,6,7,9,11,13,14,15,16],"wikipedia":11,"wild":[4,14,16],"wildcard":[1,4],"wilder":16,"willing":14,"window":[6,7,11,14],"windowsil":16,"wipe":14,"wire":[5,6,7,11,15,16],"wireless":[5,9],"wirelessli":7,"wish":[1,7,13,14,16],"within":[0,1,3,4,7,9,10,13,16],"without":[1,3,4,5,6,7,8,9,11,13,14,15,16],"wlan0":7,"wolf":5,"won":1,"word":[0,3,16],"work":[0,3,5,6,7,9,11,13,14,15],"workabl":9,"workflow":6,"world":[0,3,5,7,9,11,14,15,16],"worri":9,"worth":[0,3],"would":[0,4,7,10,11,13,14,16],"wrap":4,"write":[0,1,3,4,5,7,10,11,13,14,16],"write_timeout":1,"writer":[1,10],"written":[1,4,13,15,16],"wrong":[1,3,7,16],"wrote":[1,7],"x":[4,10,13,14],"x25519":[13,15],"x86_64":4,"xenon":1,"xonxoff":1,"y":[1,4],"ye":[3,4,7,13,14,16],"year":[13,16],"yet":[0,1,7,13,16],"yggdrasil":7,"yi":1,"you":[0,1,3,4,5,6,7,9,10,11,12,13,14,15,16],"your":[0,1,4,5,6,7,9,12,13,15,16],"yourself":[0,3,13,14,15,16],"z":1,"zen":[6,15],"zero":[6,7,10,11,15],"zi":1,"zim":11,"zip":4,"zone":[0,13],"zshrc":3},"titles":["Distributed Development","Code Examples","An Explanation of Reticulum for Human Beings","Getting Started Fast","Git Over Reticulum","Communications Hardware","Reticulum Network Stack Manual","Configuring Interfaces","Reticulum License","Building Networks","API Reference","Programs Using Reticulum","Support Reticulum","Understanding Reticulum","Using Reticulum on Your System","What is Reticulum?","Zen of Reticulum"],"titleterms":{"0":5,"1":5,"25":7,"A":16,"Beings":2,"For":16,"In":16,"Not":[9,16],"Of":[0,6,16],"Or":16,"The":[0,4,13,14,16],"To":16,"With":[3,4],"abil":16,"access":[4,13],"ad":3,"address":[9,16],"agenc":16,"alias":4,"an":2,"anchor":16,"android":3,"announc":[1,7,13,16],"api":10,"architectur":[0,16],"archiv":0,"arm64":3,"artifact":0,"attribut":4,"author":4,"auto":7,"autom":[7,14],"automat":4,"ax":7,"backbon":[3,7],"bandwidth":16,"base":[3,5],"basic":13,"beam":5,"bind":4,"blackhol":14,"block":7,"board":5,"bookworm":3,"bootstrap":3,"broadcast":1,"buffer":1,"build":[3,9],"burst":7,"byte":16,"can":15,"carrier":16,"center":[0,16],"channel":1,"chat":11,"client":[7,11],"cloud":16,"code":[1,13],"combin":5,"command":4,"commit":4,"common":7,"commun":5,"compos":0,"concept":9,"conceptu":13,"configur":[4,7,14],"connect":[3,7,9,11],"consider":[7,9],"content":6,"contribut":3,"control":7,"cost":16,"creat":[3,4,5,13],"creation":4,"creator":4,"cryptograph":[4,13],"current":[13,15],"custom":[1,3,4,7],"data":14,"death":16,"debian":3,"decentr":16,"deck":5,"depend":3,"design":16,"destin":[4,7,9,13],"detail":13,"develop":[0,3],"devic":[5,15],"disconnect":16,"discov":14,"discover":7,"discoveri":7,"distribut":[0,3],"document":4,"doe":15,"domain":16,"donat":12,"echo":[1,5],"emerg":16,"empti":4,"enabl":[4,7],"encrypt":16,"entrypoint":3,"environ":16,"establish":13,"ethernet":5,"ethic":16,"exampl":[1,4,7],"exist":16,"explan":2,"fabric":16,"fallaci":16,"fast":3,"featur":16,"feedback":12,"filesync":11,"filetransf":1,"find":3,"finish":16,"fix":14,"flow":16,"fork":4,"form":4,"format":[4,13],"forward":16,"from":16,"function":13,"further":13,"futur":13,"get":[3,13],"git":4,"global":3,"goal":13,"grade":16,"group":4,"hardwar":5,"harm":16,"health":3,"heltec":5,"heterogen":9,"hierarchi":4,"highlight":4,"host":3,"hostil":16,"human":[2,16],"i":[15,16],"i2p":7,"ident":[4,13,16],"identif":1,"illus":16,"implement":15,"implic":13,"improv":14,"includ":[3,14],"independ":16,"indic":6,"infrastructur":[0,3,16],"ingress":7,"instal":[3,5],"instanc":[3,9],"interact":[4,11],"interfac":[1,3,7,11,13,14,15,16],"intermediari":0,"internet":3,"interregnum":0,"introduct":13,"introductori":9,"ip":16,"issu":3,"j":11,"kei":13,"kiss":7,"liber":16,"licens":8,"lilygo":5,"limit":[7,16],"line":[4,5],"link":[1,13],"list":14,"listen":7,"local":14,"locat":4,"long":0,"lora":7,"lora32":5,"lunar":3,"lxmf":11,"lxmfy":11,"lxst":11,"maco":3,"manag":[4,14],"manual":[4,6],"mechan":13,"medium":16,"merit":16,"meshchatx":11,"method":4,"micron":11,"minim":1,"mirror":4,"mix":3,"mode":7,"modem":5,"modul":11,"motiv":13,"multi":7,"name":[13,14,16],"network":[3,4,6,9,11,13],"new":7,"node":[4,9,11,13,16],"nomad":[4,11,16],"note":3,"obtain":4,"offer":15,"offlin":4,"open":16,"opencom":5,"openwrt":3,"option":7,"origin":0,"over":[0,3,4],"overview":[9,13],"packet":[5,13],"page":[4,11],"paramet":[4,7],"parser":11,"path":7,"pattern":16,"permiss":4,"person":[3,16],"phone":11,"physic":16,"pi":3,"pipe":7,"platform":[0,3],"port":14,"portabl":16,"post":16,"power":16,"prerequisit":4,"presenc":16,"preserv":16,"primit":[0,13],"principl":16,"prioritis":13,"program":[3,11,14],"propag":13,"propos":4,"protocol":[0,11,13,16],"provid":12,"public":[3,13,16],"publish":14,"pure":3,"python":3,"queue":7,"radio":[3,5],"rak4631":5,"raspberri":3,"rate":7,"rbrowser":11,"reach":13,"refer":[10,13,15],"relai":11,"releas":4,"remot":[4,7,11,14],"repositori":4,"request":[1,7],"resolv":3,"resourc":[11,13],"respons":[1,3],"restor":0,"ret":3,"retibb":11,"reticulum":[2,3,4,5,6,8,11,12,13,14,15,16],"retipedia":11,"risc":3,"rn":11,"rncp":14,"rngit":[4,14],"rnid":14,"rnmon":11,"rnode":[5,7],"rnodeconf":14,"rnpath":14,"rnprobe":14,"rnsd":14,"rnsh":14,"rnstatu":14,"rnx":14,"road":0,"roam":16,"rrc":11,"rule":13,"scarciti":16,"secur":7,"serial":[5,7,14],"serv":4,"server":7,"servic":14,"setup":13,"shell":11,"short":4,"sideband":11,"sign":4,"signatur":4,"sky":16,"sourc":14,"sovereignti":[0,16],"specif":[3,13],"stack":6,"standalon":3,"start":[0,3],"state":4,"statist":4,"statu":15,"storag":4,"store":16,"strategi":3,"structur":4,"support":[5,12],"suprem":5,"synchron":4,"syntax":4,"system":[14,16],"systemwid":14,"t":5,"t114":5,"t3s3":5,"tabl":6,"tcp":7,"telephon":11,"templat":4,"through":[0,16],"time":16,"tool":16,"transport":[9,13],"trust":16,"trustless":9,"try":3,"tune":7,"type":[4,5,13,15],"ubuntu":3,"udp":7,"uncentraliz":16,"understand":13,"unsign":5,"us":[3,11,13,14,15],"usag":[5,13],"userspac":14,"util":[3,4,11,14],"v":3,"v1":5,"v2":5,"v3":5,"v4":5,"valid":4,"verif":4,"verifi":4,"wai":3,"what":15,"where":15,"wifi":5,"window":3,"wire":13,"without":0,"work":[4,16],"workflow":[0,4],"x":5,"xl":5,"your":[3,14],"zen":16,"zero":16}}) \ No newline at end of file +Search.setIndex({"alltitles":{"A Carrier-Grade Fallacy":[[17,"a-carrier-grade-fallacy"]],"A History Of What Works":[[0,"a-history-of-what-works"]],"A Persistent, But Fragile Triad":[[0,"a-persistent-but-fragile-triad"]],"API Reference":[[11,null]],"ARM64":[[4,"arm64"]],"AX.25 KISS Interface":[[8,"ax-25-kiss-interface"]],"Accessing Repository Pages":[[5,"accessing-repository-pages"]],"Addendum A: The Prns Case":[[0,"addendum-a-the-prns-case"]],"Adding Radio Interfaces":[[4,"adding-radio-interfaces"]],"Agency and answerability":[[0,"agency-and-answerability"]],"An Explanation of Reticulum for Human Beings":[[3,null]],"Anchor In The Flow":[[17,"anchor-in-the-flow"]],"Android":[[4,"android"]],"Announce":[[2,"announce"]],"Announce Propagation Rules":[[14,"announce-propagation-rules"]],"Announce Rate Control":[[8,"announce-rate-control"]],"Announcing Presence":[[17,"announcing-presence"]],"Artifact-Centered Workflows":[[1,"artifact-centered-workflows"]],"Assistance Versus Machine-Substitution":[[0,"assistance-versus-machine-substitution"]],"Author Identity Binding":[[5,"author-identity-binding"]],"Auto Interface":[[8,"auto-interface"]],"Automated Blocking":[[8,"automated-blocking"]],"Automated List Sourcing":[[15,"automated-list-sourcing"]],"Automatic Mirror Synchronization":[[5,"automatic-mirror-synchronization"]],"Backbone Interface":[[8,"backbone-interface"]],"Blackhole Management":[[15,"blackhole-management"]],"Bootstrapping Connectivity":[[4,"bootstrapping-connectivity"]],"Brandolini\u2019s Reference":[[0,null]],"Broadcast":[[2,"broadcast"]],"Browsing & Publishing":[[12,"browsing-publishing"]],"Buffer":[[2,"buffer"]],"Build Personal Infrastructure":[[4,"build-personal-infrastructure"]],"Building Networks":[[10,null]],"Channel":[[2,"channel"]],"Chat":[[12,"chat"]],"Code Examples":[[2,null]],"Columba":[[12,"id8"]],"Combining Hardware Types":[[6,"combining-hardware-types"]],"Command-Line Interaction":[[5,"command-line-interaction"]],"Commit Signing":[[5,"commit-signing"]],"Common Interface Options":[[8,"common-interface-options"]],"Communications Hardware":[[6,null]],"Composable Primitives":[[1,"composable-primitives"]],"Concepts & Overview":[[10,"concepts-overview"]],"Conceptual Overview":[[14,"conceptual-overview"]],"Conclusion":[[0,"conclusion"]],"Configuration":[[5,"configuration"],[5,"id1"]],"Configuration & Data":[[15,"configuration-data"]],"Configuration Example":[[5,"configuration-example"]],"Configuration Methods":[[5,"configuration-methods"]],"Configuring Interfaces":[[8,null]],"Connect to the Distributed Backbone":[[4,"connect-to-the-distributed-backbone"]],"Connecting Remotes":[[8,"connecting-remotes"]],"Connecting Reticulum Instances Over the Internet":[[4,"connecting-reticulum-instances-over-the-internet"]],"Consequences":[[0,"consequences"]],"Contributing to the Global Ret":[[4,"contributing-to-the-global-ret"]],"Copyright & The Two Legal Layers":[[0,"copyright-the-two-legal-layers"]],"Cost Of A Byte":[[17,"cost-of-a-byte"]],"Creating Empty Repositories":[[5,"creating-empty-repositories"]],"Creating RNodes":[[6,"creating-rnodes"]],"Creating Signed Releases":[[5,"creating-signed-releases"]],"Creating a Network With Reticulum":[[4,"creating-a-network-with-reticulum"]],"Creating and Using Custom Interfaces":[[4,"creating-and-using-custom-interfaces"]],"Creating and Using a Network Identity":[[14,"creating-and-using-a-network-identity"]],"Creator Permissions":[[5,"creator-permissions"]],"Cryptographic Attribution":[[5,"cryptographic-attribution"]],"Cryptographic Primitives":[[14,"cryptographic-primitives"]],"Current Status":[[16,"current-status"]],"Current Usage":[[14,"current-usage"]],"Custom Interfaces":[[2,"custom-interfaces"],[8,"custom-interfaces"]],"Customizing Templates":[[5,"customizing-templates"]],"Dating":[[0,"dating"]],"Death To The Address":[[17,"death-to-the-address"]],"Debian Bookworm":[[4,"debian-bookworm"]],"Decentralization Or Uncentralizability?":[[17,"decentralization-or-uncentralizability"]],"Defence Of The Commons":[[0,"defence-of-the-commons"]],"Design Patterns For Post-IP Systems":[[17,"design-patterns-for-post-ip-systems"]],"Destination Naming":[[14,"destination-naming"]],"Destinations":[[14,"destinations"]],"Destinations, Not Addresses":[[10,"destinations-not-addresses"]],"Develop a Program with Reticulum":[[4,"develop-a-program-with-reticulum"]],"Device Flashers":[[12,"device-flashers"]],"Disclosed Assistance Or Laundered Generation":[[0,"disclosed-assistance-or-laundered-generation"]],"Discoverable Interfaces":[[8,"discoverable-interfaces"]],"Discovering Interfaces":[[15,"discovering-interfaces"]],"Discovery Parameters":[[8,"discovery-parameters"]],"Distributed Development":[[1,null]],"Distribution Without Intermediaries":[[1,"distribution-without-intermediaries"]],"Donations":[[13,"donations"]],"Echo":[[2,"echo"]],"Emergent Patterns":[[17,"emergent-patterns"]],"Enabling Discovery":[[8,"enabling-discovery"]],"Enabling the Git Page Node":[[5,"enabling-the-git-page-node"]],"Encryption Is Not A Feature":[[17,"encryption-is-not-a-feature"]],"Engineering reality":[[0,"engineering-reality"]],"Ethernet-based Hardware":[[6,"ethernet-based-hardware"]],"Ethics Of The Tool":[[17,"ethics-of-the-tool"]],"Evaluating a Reticulum Implementation":[[0,"evaluating-a-reticulum-implementation"]],"Example Configuration":[[8,"example-configuration"]],"Expanding The Commons":[[0,"expanding-the-commons"]],"Fabric Of The Independent":[[17,"fabric-of-the-independent"]],"Fallacy Of The Cloud":[[17,"fallacy-of-the-cloud"]],"False Dichotomy":[[0,"false-dichotomy"]],"Filetransfer":[[2,"filetransfer"]],"Finding Your Way":[[4,"finding-your-way"]],"Fixed Serial Port Names":[[15,"fixed-serial-port-names"]],"Flow & Time":[[17,"flow-time"]],"Forking Repositories":[[5,"forking-repositories"]],"Formatting & Syntax Highlighting":[[5,"formatting-syntax-highlighting"]],"Future Implications":[[14,"future-implications"]],"Getting Further":[[14,"getting-further"]],"Getting Started Fast":[[4,null]],"Git Configuration Parameters":[[5,"git-configuration-parameters"]],"Git Over Reticulum":[[5,null],[12,"git-over-reticulum"]],"Goals":[[14,"goals"]],"Headcount":[[0,"headcount"]],"Health Is A Property Of The Whole":[[0,"health-is-a-property-of-the-whole"]],"Heltec LoRa32 v2.0":[[6,"heltec-lora32-v2-0"]],"Heltec LoRa32 v3.0":[[6,"heltec-lora32-v3-0"]],"Heltec LoRa32 v4.0":[[6,"heltec-lora32-v4-0"]],"Heltec T114":[[6,"heltec-t114"]],"Heterogeneous Connectivity":[[10,"heterogeneous-connectivity"]],"Hostile Environments":[[17,"hostile-environments"]],"Hosting Public Entrypoints":[[4,"hosting-public-entrypoints"]],"I. The Foundational Statute: Translation Is Copying":[[0,"i-the-foundational-statute-translation-is-copying"]],"I2P Interface":[[8,"i2p-interface"]],"II. Ideas Are Free, Expressions Protected":[[0,"ii-ideas-are-free-expressions-protected"]],"III. Machine Output Has No Author":[[0,"iii-machine-output-has-no-author"]],"IV. License Conditions Bound the Grant":[[0,"iv-license-conditions-bound-the-grant"]],"Identification":[[2,"example-identify"]],"Identities":[[14,"understanding-identities"]],"Identity & Destination Aliases":[[5,"identity-destination-aliases"]],"Identity and Nomadism":[[17,"identity-and-nomadism"]],"Improving System Configuration":[[15,"improving-system-configuration"]],"Included Utility Programs":[[15,"included-utility-programs"]],"Indices and Tables":[[7,"indices-and-tables"]],"Infrastructure Matters":[[0,"infrastructure-matters"]],"Installation":[[6,"installation"]],"Intent & Consequence":[[0,"intent-consequence"]],"Interface Access Codes":[[14,"interface-access-codes"]],"Interface Modes":[[8,"interface-modes"],[8,"interfaces-modes"]],"Interface Modules & Connectivity Resources":[[12,"interface-modules-connectivity-resources"]],"Interface Types and Devices":[[16,"interface-types-and-devices"]],"Introduction & Basic Functionality":[[14,"introduction-basic-functionality"]],"Introductory Considerations":[[10,"introductory-considerations"]],"KISS Interface":[[8,"kiss-interface"]],"LXMF":[[12,"lxmf"]],"LXMFy":[[12,"lxmfy"]],"LXST":[[12,"id30"]],"LXST Phone":[[12,"lxst-phone"]],"Liberation From Limits":[[17,"liberation-from-limits"]],"Licensing Analysis":[[0,"licensing-analysis"]],"LilyGO LoRa32 v1.0":[[6,"lilygo-lora32-v1-0"]],"LilyGO LoRa32 v2.0":[[6,"lilygo-lora32-v2-0"]],"LilyGO LoRa32 v2.1":[[6,"lilygo-lora32-v2-1"]],"LilyGO T-Beam":[[6,"lilygo-t-beam"]],"LilyGO T-Beam Supreme":[[6,"lilygo-t-beam-supreme"]],"LilyGO T-Deck":[[6,"lilygo-t-deck"]],"LilyGO T-Echo":[[6,"lilygo-t-echo"]],"LilyGO T3S3":[[6,"lilygo-t3s3"]],"Link":[[2,"link"]],"Link Establishment in Detail":[[14,"link-establishment-in-detail"]],"Listeners":[[8,"listeners"]],"Local Blackhole Management":[[15,"local-blackhole-management"]],"Long Archive":[[1,"long-archive"]],"MacOS":[[4,"macos"]],"Managing Group Permissions":[[5,"managing-group-permissions"]],"Managing Repository Permissions":[[5,"managing-repository-permissions"]],"Managing Work Document Permissions":[[5,"managing-work-document-permissions"]],"Manual Synchronization":[[5,"manual-synchronization"]],"Merits Of Scarcity":[[17,"merits-of-scarcity"]],"MeshChatX":[[12,"id6"]],"Messaging & Voice":[[12,"messaging-voice"]],"Micron Parser JS":[[12,"micron-parser-js"]],"Minimal":[[2,"minimal"]],"Mirroring Repositories":[[5,"mirroring-repositories"]],"Mixing Strategies":[[4,"mixing-strategies"]],"Modem73":[[12,"modem73"]],"Monetary and influence signals":[[0,"monetary-and-influence-signals"]],"Motivation":[[14,"motivation"]],"Naming Is Power":[[17,"naming-is-power"]],"Network Health & Coexistence":[[0,"network-health-coexistence"]],"Network Health & Responsibility":[[4,"network-health-responsibility"]],"Network Identities":[[14,"network-identities"]],"Network citizenship":[[0,"network-citizenship"]],"New Destination Rate Limiting":[[8,"new-destination-rate-limiting"]],"Node Types":[[14,"node-types"]],"Nomad Network":[[12,"nomad-network"]],"Obtaining Verified Releases":[[5,"obtaining-verified-releases"]],"Offline Verification":[[5,"offline-verification"]],"On Freedom":[[0,"on-freedom"]],"On The Institutions, In Fairness":[[0,"on-the-institutions-in-fairness"]],"Open Sky":[[17,"open-sky"]],"Open Source Means Open Source":[[0,"open-source-means-open-source"]],"OpenCom XL":[[6,"opencom-xl"]],"OpenWRT":[[4,"openwrt"]],"Other Signals To Look For":[[0,"other-signals-to-look-for"]],"Overall Evaluation":[[0,"overall-evaluation"]],"Packet Prioritisation":[[14,"packet-prioritisation"]],"Packet Radio Modems":[[6,"packet-radio-modems"]],"Partyline":[[12,"partyline"]],"Path Request Burst Control":[[8,"path-request-burst-control"]],"Permission Configuration Locations":[[5,"permission-configuration-locations"]],"Permission Examples":[[5,"permission-examples"]],"Permission Hierarchy":[[5,"permission-hierarchy"]],"Permission Short Forms":[[5,"permission-short-forms"]],"Permission Types":[[5,"permission-types"]],"Permission Validation":[[5,"permission-validation"]],"Permissions":[[5,"permissions"]],"Personal Infrastructure":[[17,"personal-infrastructure"]],"Physics Of Trust":[[17,"physics-of-trust"]],"Pipe Interface":[[8,"pipe-interface"]],"Platform-Specific Install Notes":[[4,"platform-specific-install-notes"]],"Portable Existence":[[17,"portable-existence"]],"Possible Verdicts":[[0,"possible-verdicts"]],"Prerequisites":[[5,"prerequisites"]],"Presentation, Elongated":[[0,"presentation-elongated"]],"Preserving Human Agency":[[17,"preserving-human-agency"]],"Programs Using Reticulum":[[12,null]],"Proposing Work Documents":[[5,"proposing-work-documents"]],"Protocol Specifics":[[14,"protocol-specifics"]],"Protocols":[[12,"protocols"]],"Protocols Over Platforms":[[1,"protocols-over-platforms"]],"Provenance and attribution":[[0,"provenance-and-attribution"]],"Provide Feedback":[[13,"provide-feedback"]],"Public Domain Protocol":[[17,"public-domain-protocol"]],"Public Key Announcements":[[14,"public-key-announcements"]],"Publishing Blackhole Lists":[[15,"publishing-blackhole-lists"]],"Pure-Python Reticulum":[[4,"pure-python-reticulum"]],"Purpose & Scope":[[0,"purpose-scope"]],"Question 1: Is this a clean implementation, or was it directly generated from the reference?":[[0,"question-1-is-this-a-clean-implementation-or-was-it-directly-generated-from-the-reference"]],"Question 2: Who, or what, is the agent of the work?":[[0,"question-2-who-or-what-is-the-agent-of-the-work"]],"RAK4631-based Boards":[[6,"rak4631-based-boards"]],"RISC-V":[[4,"risc-v"]],"RNMon":[[12,"rnmon"]],"RNS FileSync":[[12,"rns-filesync"]],"RNS Page Node":[[12,"rns-page-node"]],"RNode":[[6,"rnode"]],"RNode LoRa Interface":[[8,"rnode-lora-interface"]],"RNode Multi Interface":[[8,"rnode-multi-interface"]],"RRC":[[12,"rrc"]],"Raspberry Pi":[[4,"raspberry-pi"]],"Reaching the Destination":[[14,"reaching-the-destination"]],"Recognition & Response":[[0,"recognition-response"]],"Recycled Wine, Fermenting":[[0,"recycled-wine-fermenting"]],"Reference Implementation":[[16,"reference-implementation"]],"Reference Setup":[[14,"reference-setup"]],"Release Management":[[5,"release-management"]],"Release Storage & Structure":[[5,"release-storage-structure"]],"Remote Management":[[15,"remote-management"]],"Remote Permission Management":[[5,"remote-permission-management"]],"Remote Shell":[[12,"remote-shell"]],"Ren Browser":[[12,"ren-browser"]],"Ren TUI":[[12,"ren-tui"]],"Repository Creation & Management":[[5,"repository-creation-management"]],"Repository Statistics":[[5,"repository-statistics"]],"Repository Structure":[[5,"repository-structure"]],"Requests & Responses":[[2,"requests-responses"]],"Resolving Dependency & Installation Issues":[[4,"resolving-dependency-installation-issues"]],"Resources":[[14,"resources"]],"Restoration":[[1,"restoration"]],"RetiBBS":[[12,"retibbs"]],"Reticulated":[[12,"reticulated"]],"Reticulum License":[[9,null]],"Reticulum Network Stack Manual":[[7,null]],"Reticulum Network Telephone":[[12,"reticulum-network-telephone"]],"Reticulum Relay Chat":[[12,"reticulum-relay-chat"]],"Reticulum Transport":[[14,"reticulum-transport"]],"Reticulum as a System Service":[[15,"reticulum-as-a-system-service"]],"Retipedia":[[12,"retipedia"]],"Roaming Nodes":[[17,"roaming-nodes"]],"Security Considerations":[[8,"security-considerations"]],"Serial Interface":[[8,"serial-interface"]],"Serial Lines & Devices":[[6,"serial-lines-devices"]],"Serving Pages Over Nomad Network":[[5,"serving-pages-over-nomad-network"]],"Sideband":[[12,"sideband"]],"Signing Commits":[[5,"signing-commits"]],"Sources and Authorities":[[0,"sources-and-authorities"]],"Sovereignty Through Infrastructure":[[1,"sovereignty-through-infrastructure"],[17,"sovereignty-through-infrastructure"]],"Standalone Reticulum Installation":[[4,"standalone-reticulum-installation"]],"Start Of The Road":[[1,"start-of-the-road"]],"State Management":[[5,"state-management"]],"Store & Forward":[[17,"store-forward"]],"Substance Of The Networks":[[0,"substance-of-the-networks"]],"Support Reticulum":[[13,null]],"Supported Boards and Devices":[[6,"supported-boards-and-devices"]],"System Administration":[[12,"system-administration"]],"Systemwide Service":[[15,"systemwide-service"]],"TCP Client Interface":[[8,"tcp-client-interface"]],"TCP Server Interface":[[8,"tcp-server-interface"]],"Table Of Contents":[[7,"table-of-contents"]],"The Ability To Disconnect":[[17,"the-ability-to-disconnect"]],"The Announce Mechanism in Detail":[[14,"the-announce-mechanism-in-detail"]],"The Bandwidth Fallacy":[[17,"the-bandwidth-fallacy"]],"The Conformal Surface":[[0,"the-conformal-surface"]],"The Consequences Of The \u201cNot Open Source\u201d Claim":[[0,"the-consequences-of-the-not-open-source-claim"]],"The Distribution Argument":[[0,"the-distribution-argument"]],"The Fluency Trap":[[0,"the-fluency-trap"]],"The General Principle":[[0,"the-general-principle"]],"The Harm Principle":[[17,"the-harm-principle"]],"The Illusion Of The Center":[[17,"the-illusion-of-the-center"]],"The Intention Of This Guide":[[0,"the-intention-of-this-guide"]],"The Interface Is The Medium":[[17,"the-interface-is-the-medium"]],"The License In This Context":[[0,"the-license-in-this-context"]],"The Line":[[0,"the-line"]],"The Method of Madness":[[0,"the-method-of-madness"]],"The Movement Of A Dozen":[[0,"the-movement-of-a-dozen"]],"The Original Architecture":[[1,"the-original-architecture"]],"The Place Of New Implementations":[[0,"the-place-of-new-implementations"]],"The Platform Interregnum":[[1,"the-platform-interregnum"]],"The Prediction, And What Happened":[[0,"the-prediction-and-what-happened"]],"The Project In Brief":[[0,"the-project-in-brief"]],"The Release Workflow":[[5,"the-release-workflow"]],"The Role Of The Individual":[[0,"the-role-of-the-individual"]],"The Work Is Finished":[[17,"the-work-is-finished"]],"The performance claims":[[0,"the-performance-claims"]],"The rncp Utility":[[15,"the-rncp-utility"]],"The rngit Utility":[[5,"the-rngit-utility"],[15,"the-rngit-utility"]],"The rnid Utility":[[15,"the-rnid-utility"]],"The rnodeconf Utility":[[15,"the-rnodeconf-utility"]],"The rnpath Utility":[[15,"the-rnpath-utility"]],"The rnprobe Utility":[[15,"the-rnprobe-utility"]],"The rnsd Utility":[[15,"the-rnsd-utility"]],"The rnsh Utility":[[15,"the-rnsh-utility"]],"The rnstatus Utility":[[15,"the-rnstatus-utility"]],"The rnx Utility":[[15,"the-rnx-utility"]],"The \u201cClean-Room\u201d Delusion":[[0,"the-clean-room-delusion"]],"These Standards Are Reasonable":[[0,"these-standards-are-reasonable"]],"Transport Nodes and Instances":[[10,"transport-nodes-and-instances"]],"Trustless Networking":[[10,"trustless-networking"]],"Try Using a Reticulum-based Program":[[4,"try-using-a-reticulum-based-program"]],"Tuning Ingress Queues":[[8,"tuning-ingress-queues"]],"Two Questions That Resolve Most Cases":[[0,"two-questions-that-resolve-most-cases"]],"UDP Interface":[[8,"udp-interface"]],"Ubuntu Lunar":[[4,"ubuntu-lunar"]],"Understanding Reticulum":[[14,null]],"Unsigned RNode v2.x":[[6,"unsigned-rnode-v2-x"]],"Usage with Reticulum":[[6,"usage-with-reticulum"]],"Userspace Service":[[15,"userspace-service"]],"Using Reticulum on Your System":[[15,null]],"Using the Included Utilities":[[4,"using-the-included-utilities"]],"Utilities & Components":[[12,"utilities-components"]],"V. The Void Grant":[[0,"v-the-void-grant"]],"VI. Fair Use Does Not Rescue This Pattern":[[0,"vi-fair-use-does-not-rescue-this-pattern"]],"Validating Commit Signatures":[[5,"validating-commit-signatures"]],"Verdict":[[0,"verdict"]],"Verified Releases":[[5,"verified-releases"]],"Voice & Telephony":[[12,"voice-telephony"]],"Void Grants: Legal Foundations of Machine-Generated Code":[[0,"void-grants-legal-foundations-of-machine-generated-code"]],"What The Argument Is Actually Doing":[[0,"what-the-argument-is-actually-doing"]],"What The Pattern Is Not":[[0,"what-the-pattern-is-not"]],"What The Reticulum License Is":[[0,"what-the-reticulum-license-is"]],"What This Means For Other Implementations":[[0,"what-this-means-for-other-implementations"]],"What assistance looks like":[[0,"what-assistance-looks-like"]],"What does Reticulum Offer?":[[16,"what-does-reticulum-offer"]],"What is Reticulum?":[[16,null]],"What substitution looks like":[[0,"what-substitution-looks-like"]],"What \u201cOpen\u201d Means Positively":[[0,"what-open-means-positively"]],"Where can Reticulum be Used?":[[16,"where-can-reticulum-be-used"]],"Who Is Restricted By Which License?":[[0,"who-is-restricted-by-which-license"]],"Why This License Exists":[[0,"why-this-license-exists"]],"WiFi-based Hardware":[[6,"wifi-based-hardware"]],"Windows":[[4,"windows"]],"Wire Format":[[14,"wire-format"]],"Work Document Permissions":[[5,"work-document-permissions"]],"Work Documents":[[5,"work-documents"]],"Working With Work Documents":[[5,"working-with-work-documents"]],"Zen of Reticulum":[[17,null]],"Zero-Trust Architectures":[[17,"zero-trust-architectures"]]},"docnames":["brandolinis","distributed","examples","forhumans","gettingstartedfast","git","hardware","index","interfaces","license","networks","reference","software","support","understanding","using","whatis","zen"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2},"filenames":["brandolinis.rst","distributed.rst","examples.rst","forhumans.rst","gettingstartedfast.rst","git.rst","hardware.rst","index.rst","interfaces.rst","license.rst","networks.rst","reference.rst","software.rst","support.rst","understanding.rst","using.rst","whatis.rst","zen.rst"],"indexentries":{"__init__() (rns.rawchannelreader method)":[[11,"RNS.RawChannelReader.__init__",false]],"__init__() (rns.rawchannelwriter method)":[[11,"RNS.RawChannelWriter.__init__",false]],"accepts_links() (rns.destination method)":[[11,"RNS.Destination.accepts_links",false]],"add_message_handler() (rns.channel.channel method)":[[11,"RNS.Channel.Channel.add_message_handler",false]],"add_ready_callback() (rns.rawchannelreader method)":[[11,"RNS.RawChannelReader.add_ready_callback",false]],"advertise() (rns.resource method)":[[11,"RNS.Resource.advertise",false]],"announce() (rns.destination method)":[[11,"RNS.Destination.announce",false]],"announce_cap (rns.reticulum attribute)":[[11,"RNS.Reticulum.ANNOUNCE_CAP",false]],"app_and_aspects_from_name() (rns.destination static method)":[[11,"RNS.Destination.app_and_aspects_from_name",false]],"await_path() (rns.transport static method)":[[11,"RNS.Transport.await_path",false]],"blackhole_identity() (rns.transport static method)":[[11,"RNS.Transport.blackhole_identity",false]],"blackhole_sources() (rns.reticulum static method)":[[11,"RNS.Reticulum.blackhole_sources",false]],"buffer (class in rns)":[[11,"RNS.Buffer",false]],"cancel() (rns.resource method)":[[11,"RNS.Resource.cancel",false]],"channel (class in rns.channel)":[[11,"RNS.Channel.Channel",false]],"clear_default_app_data() (rns.destination method)":[[11,"RNS.Destination.clear_default_app_data",false]],"concluded() (rns.requestreceipt method)":[[11,"RNS.RequestReceipt.concluded",false]],"create_bidirectional_buffer() (rns.buffer static method)":[[11,"RNS.Buffer.create_bidirectional_buffer",false]],"create_keys() (rns.destination method)":[[11,"RNS.Destination.create_keys",false]],"create_reader() (rns.buffer static method)":[[11,"RNS.Buffer.create_reader",false]],"create_writer() (rns.buffer static method)":[[11,"RNS.Buffer.create_writer",false]],"current_ratchet_id() (rns.identity static method)":[[11,"RNS.Identity.current_ratchet_id",false]],"curve (rns.identity attribute)":[[11,"RNS.Identity.CURVE",false]],"curve (rns.link attribute)":[[11,"RNS.Link.CURVE",false]],"decrypt() (rns.destination method)":[[11,"RNS.Destination.decrypt",false]],"decrypt() (rns.identity method)":[[11,"RNS.Identity.decrypt",false]],"default_per_hop_timeout (rns.reticulum attribute)":[[11,"RNS.Reticulum.DEFAULT_PER_HOP_TIMEOUT",false]],"deregister_announce_handler() (rns.transport static method)":[[11,"RNS.Transport.deregister_announce_handler",false]],"deregister_request_handler() (rns.destination method)":[[11,"RNS.Destination.deregister_request_handler",false]],"destination (class in rns)":[[11,"RNS.Destination",false]],"discovered_interfaces() (rns.reticulum static method)":[[11,"RNS.Reticulum.discovered_interfaces",false]],"enable_ratchets() (rns.destination method)":[[11,"RNS.Destination.enable_ratchets",false]],"encrypt() (rns.destination method)":[[11,"RNS.Destination.encrypt",false]],"encrypt() (rns.identity method)":[[11,"RNS.Identity.encrypt",false]],"encrypted_mdu (rns.packet attribute)":[[11,"RNS.Packet.ENCRYPTED_MDU",false]],"enforce_ratchets() (rns.destination method)":[[11,"RNS.Destination.enforce_ratchets",false]],"establishment_timeout_per_hop (rns.link attribute)":[[11,"RNS.Link.ESTABLISHMENT_TIMEOUT_PER_HOP",false]],"expand_name() (rns.destination static method)":[[11,"RNS.Destination.expand_name",false]],"from_bytes() (rns.identity static method)":[[11,"RNS.Identity.from_bytes",false]],"from_file() (rns.identity static method)":[[11,"RNS.Identity.from_file",false]],"full_hash() (rns.identity static method)":[[11,"RNS.Identity.full_hash",false]],"get_age() (rns.link method)":[[11,"RNS.Link.get_age",false]],"get_channel() (rns.link method)":[[11,"RNS.Link.get_channel",false]],"get_data_size() (rns.resource method)":[[11,"RNS.Resource.get_data_size",false]],"get_establishment_rate() (rns.link method)":[[11,"RNS.Link.get_establishment_rate",false]],"get_expected_rate() (rns.link method)":[[11,"RNS.Link.get_expected_rate",false]],"get_first_hop_timeout() (rns.reticulum method)":[[11,"RNS.Reticulum.get_first_hop_timeout",false]],"get_hash() (rns.resource method)":[[11,"RNS.Resource.get_hash",false]],"get_instance() (rns.reticulum static method)":[[11,"RNS.Reticulum.get_instance",false]],"get_lowest_interface_bitrate() (rns.reticulum method)":[[11,"RNS.Reticulum.get_lowest_interface_bitrate",false]],"get_mdu() (rns.link method)":[[11,"RNS.Link.get_mdu",false]],"get_medium_path_timeout() (rns.reticulum method)":[[11,"RNS.Reticulum.get_medium_path_timeout",false]],"get_mode() (rns.link method)":[[11,"RNS.Link.get_mode",false]],"get_mtu() (rns.link method)":[[11,"RNS.Link.get_mtu",false]],"get_parts() (rns.resource method)":[[11,"RNS.Resource.get_parts",false]],"get_private_key() (rns.destination method)":[[11,"RNS.Destination.get_private_key",false]],"get_private_key() (rns.identity method)":[[11,"RNS.Identity.get_private_key",false]],"get_progress() (rns.requestreceipt method)":[[11,"RNS.RequestReceipt.get_progress",false]],"get_progress() (rns.resource method)":[[11,"RNS.Resource.get_progress",false]],"get_public_key() (rns.identity method)":[[11,"RNS.Identity.get_public_key",false]],"get_q() (rns.link method)":[[11,"RNS.Link.get_q",false]],"get_q() (rns.packet method)":[[11,"RNS.Packet.get_q",false]],"get_random_hash() (rns.identity static method)":[[11,"RNS.Identity.get_random_hash",false]],"get_remote_identity() (rns.link method)":[[11,"RNS.Link.get_remote_identity",false]],"get_request_id() (rns.requestreceipt method)":[[11,"RNS.RequestReceipt.get_request_id",false]],"get_response() (rns.requestreceipt method)":[[11,"RNS.RequestReceipt.get_response",false]],"get_response_time() (rns.requestreceipt method)":[[11,"RNS.RequestReceipt.get_response_time",false]],"get_rssi() (rns.link method)":[[11,"RNS.Link.get_rssi",false]],"get_rssi() (rns.packet method)":[[11,"RNS.Packet.get_rssi",false]],"get_rtt() (rns.packetreceipt method)":[[11,"RNS.PacketReceipt.get_rtt",false]],"get_segments() (rns.resource method)":[[11,"RNS.Resource.get_segments",false]],"get_snr() (rns.link method)":[[11,"RNS.Link.get_snr",false]],"get_snr() (rns.packet method)":[[11,"RNS.Packet.get_snr",false]],"get_status() (rns.packetreceipt method)":[[11,"RNS.PacketReceipt.get_status",false]],"get_status() (rns.requestreceipt method)":[[11,"RNS.RequestReceipt.get_status",false]],"get_transfer_size() (rns.resource method)":[[11,"RNS.Resource.get_transfer_size",false]],"has_path() (rns.transport static method)":[[11,"RNS.Transport.has_path",false]],"hash() (rns.destination static method)":[[11,"RNS.Destination.hash",false]],"hash_from_name_and_identity() (rns.destination static method)":[[11,"RNS.Destination.hash_from_name_and_identity",false]],"hops_to() (rns.transport static method)":[[11,"RNS.Transport.hops_to",false]],"identify() (rns.link method)":[[11,"RNS.Link.identify",false]],"identity (class in rns)":[[11,"RNS.Identity",false]],"inactive_for() (rns.link method)":[[11,"RNS.Link.inactive_for",false]],"interface_discovery_sources() (rns.reticulum static method)":[[11,"RNS.Reticulum.interface_discovery_sources",false]],"is_compressed() (rns.resource method)":[[11,"RNS.Resource.is_compressed",false]],"is_ready_to_send() (rns.channel.channel method)":[[11,"RNS.Channel.Channel.is_ready_to_send",false]],"keepalive (rns.link attribute)":[[11,"RNS.Link.KEEPALIVE",false]],"keepalive_timeout_factor (rns.link attribute)":[[11,"RNS.Link.KEEPALIVE_TIMEOUT_FACTOR",false]],"keysize (rns.identity attribute)":[[11,"RNS.Identity.KEYSIZE",false]],"link (class in rns)":[[11,"RNS.Link",false]],"link_mtu_discovery (rns.reticulum attribute)":[[11,"RNS.Reticulum.LINK_MTU_DISCOVERY",false]],"link_mtu_discovery() (rns.reticulum static method)":[[11,"RNS.Reticulum.link_mtu_discovery",false]],"load_private_key() (rns.destination method)":[[11,"RNS.Destination.load_private_key",false]],"load_private_key() (rns.identity method)":[[11,"RNS.Identity.load_private_key",false]],"load_public_key() (rns.identity method)":[[11,"RNS.Identity.load_public_key",false]],"mdu (rns.channel.channel property)":[[11,"RNS.Channel.Channel.mdu",false]],"messagebase (class in rns)":[[11,"RNS.MessageBase",false]],"minimum_bitrate (rns.reticulum attribute)":[[11,"RNS.Reticulum.MINIMUM_BITRATE",false]],"msgtype (rns.messagebase attribute)":[[11,"RNS.MessageBase.MSGTYPE",false]],"mtu (rns.reticulum attribute)":[[11,"RNS.Reticulum.MTU",false]],"next_hop() (rns.transport static method)":[[11,"RNS.Transport.next_hop",false]],"next_hop_interface() (rns.transport static method)":[[11,"RNS.Transport.next_hop_interface",false]],"no_data_for() (rns.link method)":[[11,"RNS.Link.no_data_for",false]],"no_inbound_for() (rns.link method)":[[11,"RNS.Link.no_inbound_for",false]],"no_outbound_for() (rns.link method)":[[11,"RNS.Link.no_outbound_for",false]],"pack() (rns.messagebase method)":[[11,"RNS.MessageBase.pack",false]],"packet (class in rns)":[[11,"RNS.Packet",false]],"packetreceipt (class in rns)":[[11,"RNS.PacketReceipt",false]],"pathfinder_m (rns.transport attribute)":[[11,"RNS.Transport.PATHFINDER_M",false]],"plain_mdu (rns.packet attribute)":[[11,"RNS.Packet.PLAIN_MDU",false]],"pub_to_file() (rns.identity method)":[[11,"RNS.Identity.pub_to_file",false]],"publish_blackhole_enabled() (rns.reticulum static method)":[[11,"RNS.Reticulum.publish_blackhole_enabled",false]],"ratchet_count (rns.destination attribute)":[[11,"RNS.Destination.RATCHET_COUNT",false]],"ratchet_expiry (rns.identity attribute)":[[11,"RNS.Identity.RATCHET_EXPIRY",false]],"ratchet_interval (rns.destination attribute)":[[11,"RNS.Destination.RATCHET_INTERVAL",false]],"ratchetsize (rns.identity attribute)":[[11,"RNS.Identity.RATCHETSIZE",false]],"rawchannelreader (class in rns)":[[11,"RNS.RawChannelReader",false]],"rawchannelwriter (class in rns)":[[11,"RNS.RawChannelWriter",false]],"recall() (rns.identity static method)":[[11,"RNS.Identity.recall",false]],"recall_app_data() (rns.identity static method)":[[11,"RNS.Identity.recall_app_data",false]],"register_announce_handler() (rns.transport static method)":[[11,"RNS.Transport.register_announce_handler",false]],"register_message_type() (rns.channel.channel method)":[[11,"RNS.Channel.Channel.register_message_type",false]],"register_request_handler() (rns.destination method)":[[11,"RNS.Destination.register_request_handler",false]],"remote_management_enabled() (rns.reticulum static method)":[[11,"RNS.Reticulum.remote_management_enabled",false]],"remove_message_handler() (rns.channel.channel method)":[[11,"RNS.Channel.Channel.remove_message_handler",false]],"remove_ready_callback() (rns.rawchannelreader method)":[[11,"RNS.RawChannelReader.remove_ready_callback",false]],"request() (rns.link method)":[[11,"RNS.Link.request",false]],"request_path() (rns.transport static method)":[[11,"RNS.Transport.request_path",false]],"requestreceipt (class in rns)":[[11,"RNS.RequestReceipt",false]],"required_discovery_value() (rns.reticulum static method)":[[11,"RNS.Reticulum.required_discovery_value",false]],"resend() (rns.packet method)":[[11,"RNS.Packet.resend",false]],"resource (class in rns)":[[11,"RNS.Resource",false]],"reticulum (class in rns)":[[11,"RNS.Reticulum",false]],"send() (rns.channel.channel method)":[[11,"RNS.Channel.Channel.send",false]],"send() (rns.packet method)":[[11,"RNS.Packet.send",false]],"set_default_app_data() (rns.destination method)":[[11,"RNS.Destination.set_default_app_data",false]],"set_delivery_callback() (rns.packetreceipt method)":[[11,"RNS.PacketReceipt.set_delivery_callback",false]],"set_link_closed_callback() (rns.link method)":[[11,"RNS.Link.set_link_closed_callback",false]],"set_link_established_callback() (rns.destination method)":[[11,"RNS.Destination.set_link_established_callback",false]],"set_max_request_size() (rns.destination method)":[[11,"RNS.Destination.set_max_request_size",false]],"set_packet_callback() (rns.destination method)":[[11,"RNS.Destination.set_packet_callback",false]],"set_packet_callback() (rns.link method)":[[11,"RNS.Link.set_packet_callback",false]],"set_proof_requested_callback() (rns.destination method)":[[11,"RNS.Destination.set_proof_requested_callback",false]],"set_proof_strategy() (rns.destination method)":[[11,"RNS.Destination.set_proof_strategy",false]],"set_ratchet_interval() (rns.destination method)":[[11,"RNS.Destination.set_ratchet_interval",false]],"set_remote_identified_callback() (rns.link method)":[[11,"RNS.Link.set_remote_identified_callback",false]],"set_resource_callback() (rns.link method)":[[11,"RNS.Link.set_resource_callback",false]],"set_resource_concluded_callback() (rns.link method)":[[11,"RNS.Link.set_resource_concluded_callback",false]],"set_resource_started_callback() (rns.link method)":[[11,"RNS.Link.set_resource_started_callback",false]],"set_resource_strategy() (rns.link method)":[[11,"RNS.Link.set_resource_strategy",false]],"set_retained_ratchets() (rns.destination method)":[[11,"RNS.Destination.set_retained_ratchets",false]],"set_timeout() (rns.packetreceipt method)":[[11,"RNS.PacketReceipt.set_timeout",false]],"set_timeout_callback() (rns.packetreceipt method)":[[11,"RNS.PacketReceipt.set_timeout_callback",false]],"should_use_implicit_proof() (rns.reticulum static method)":[[11,"RNS.Reticulum.should_use_implicit_proof",false]],"sign() (rns.destination method)":[[11,"RNS.Destination.sign",false]],"sign() (rns.identity method)":[[11,"RNS.Identity.sign",false]],"stale_grace (rns.link attribute)":[[11,"RNS.Link.STALE_GRACE",false]],"stale_time (rns.link attribute)":[[11,"RNS.Link.STALE_TIME",false]],"teardown() (rns.link method)":[[11,"RNS.Link.teardown",false]],"to_file() (rns.identity method)":[[11,"RNS.Identity.to_file",false]],"track_phy_stats() (rns.link method)":[[11,"RNS.Link.track_phy_stats",false]],"transport (class in rns)":[[11,"RNS.Transport",false]],"transport_enabled() (rns.reticulum static method)":[[11,"RNS.Reticulum.transport_enabled",false]],"truncated_hash() (rns.identity static method)":[[11,"RNS.Identity.truncated_hash",false]],"truncated_hashlength (rns.identity attribute)":[[11,"RNS.Identity.TRUNCATED_HASHLENGTH",false]],"unblackhole_identity() (rns.transport static method)":[[11,"RNS.Transport.unblackhole_identity",false]],"unpack() (rns.messagebase method)":[[11,"RNS.MessageBase.unpack",false]],"validate() (rns.identity method)":[[11,"RNS.Identity.validate",false]]},"objects":{"RNS":[[11,0,1,"","Buffer"],[11,0,1,"","Destination"],[11,0,1,"","Identity"],[11,0,1,"","Link"],[11,0,1,"","MessageBase"],[11,0,1,"","Packet"],[11,0,1,"","PacketReceipt"],[11,0,1,"","RawChannelReader"],[11,0,1,"","RawChannelWriter"],[11,0,1,"","RequestReceipt"],[11,0,1,"","Resource"],[11,0,1,"","Reticulum"],[11,0,1,"","Transport"]],"RNS.Buffer":[[11,1,1,"","create_bidirectional_buffer"],[11,1,1,"","create_reader"],[11,1,1,"","create_writer"]],"RNS.Channel":[[11,0,1,"","Channel"]],"RNS.Channel.Channel":[[11,1,1,"","add_message_handler"],[11,1,1,"","is_ready_to_send"],[11,2,1,"","mdu"],[11,1,1,"","register_message_type"],[11,1,1,"","remove_message_handler"],[11,1,1,"","send"]],"RNS.Destination":[[11,3,1,"","RATCHET_COUNT"],[11,3,1,"","RATCHET_INTERVAL"],[11,1,1,"","accepts_links"],[11,1,1,"","announce"],[11,1,1,"","app_and_aspects_from_name"],[11,1,1,"","clear_default_app_data"],[11,1,1,"","create_keys"],[11,1,1,"","decrypt"],[11,1,1,"","deregister_request_handler"],[11,1,1,"","enable_ratchets"],[11,1,1,"","encrypt"],[11,1,1,"","enforce_ratchets"],[11,1,1,"","expand_name"],[11,1,1,"","get_private_key"],[11,1,1,"","hash"],[11,1,1,"","hash_from_name_and_identity"],[11,1,1,"","load_private_key"],[11,1,1,"","register_request_handler"],[11,1,1,"","set_default_app_data"],[11,1,1,"","set_link_established_callback"],[11,1,1,"","set_max_request_size"],[11,1,1,"","set_packet_callback"],[11,1,1,"","set_proof_requested_callback"],[11,1,1,"","set_proof_strategy"],[11,1,1,"","set_ratchet_interval"],[11,1,1,"","set_retained_ratchets"],[11,1,1,"","sign"]],"RNS.Identity":[[11,3,1,"","CURVE"],[11,3,1,"","KEYSIZE"],[11,3,1,"","RATCHETSIZE"],[11,3,1,"","RATCHET_EXPIRY"],[11,3,1,"","TRUNCATED_HASHLENGTH"],[11,1,1,"","current_ratchet_id"],[11,1,1,"","decrypt"],[11,1,1,"","encrypt"],[11,1,1,"","from_bytes"],[11,1,1,"","from_file"],[11,1,1,"","full_hash"],[11,1,1,"","get_private_key"],[11,1,1,"","get_public_key"],[11,1,1,"","get_random_hash"],[11,1,1,"","load_private_key"],[11,1,1,"","load_public_key"],[11,1,1,"","pub_to_file"],[11,1,1,"","recall"],[11,1,1,"","recall_app_data"],[11,1,1,"","sign"],[11,1,1,"","to_file"],[11,1,1,"","truncated_hash"],[11,1,1,"","validate"]],"RNS.Link":[[11,3,1,"","CURVE"],[11,3,1,"","ESTABLISHMENT_TIMEOUT_PER_HOP"],[11,3,1,"","KEEPALIVE"],[11,3,1,"","KEEPALIVE_TIMEOUT_FACTOR"],[11,3,1,"","STALE_GRACE"],[11,3,1,"","STALE_TIME"],[11,1,1,"","get_age"],[11,1,1,"","get_channel"],[11,1,1,"","get_establishment_rate"],[11,1,1,"","get_expected_rate"],[11,1,1,"","get_mdu"],[11,1,1,"","get_mode"],[11,1,1,"","get_mtu"],[11,1,1,"","get_q"],[11,1,1,"","get_remote_identity"],[11,1,1,"","get_rssi"],[11,1,1,"","get_snr"],[11,1,1,"","identify"],[11,1,1,"","inactive_for"],[11,1,1,"","no_data_for"],[11,1,1,"","no_inbound_for"],[11,1,1,"","no_outbound_for"],[11,1,1,"","request"],[11,1,1,"","set_link_closed_callback"],[11,1,1,"","set_packet_callback"],[11,1,1,"","set_remote_identified_callback"],[11,1,1,"","set_resource_callback"],[11,1,1,"","set_resource_concluded_callback"],[11,1,1,"","set_resource_started_callback"],[11,1,1,"","set_resource_strategy"],[11,1,1,"","teardown"],[11,1,1,"","track_phy_stats"]],"RNS.MessageBase":[[11,3,1,"","MSGTYPE"],[11,1,1,"","pack"],[11,1,1,"","unpack"]],"RNS.Packet":[[11,3,1,"","ENCRYPTED_MDU"],[11,3,1,"","PLAIN_MDU"],[11,1,1,"","get_q"],[11,1,1,"","get_rssi"],[11,1,1,"","get_snr"],[11,1,1,"","resend"],[11,1,1,"","send"]],"RNS.PacketReceipt":[[11,1,1,"","get_rtt"],[11,1,1,"","get_status"],[11,1,1,"","set_delivery_callback"],[11,1,1,"","set_timeout"],[11,1,1,"","set_timeout_callback"]],"RNS.RawChannelReader":[[11,1,1,"","__init__"],[11,1,1,"","add_ready_callback"],[11,1,1,"","remove_ready_callback"]],"RNS.RawChannelWriter":[[11,1,1,"","__init__"]],"RNS.RequestReceipt":[[11,1,1,"","concluded"],[11,1,1,"","get_progress"],[11,1,1,"","get_request_id"],[11,1,1,"","get_response"],[11,1,1,"","get_response_time"],[11,1,1,"","get_status"]],"RNS.Resource":[[11,1,1,"","advertise"],[11,1,1,"","cancel"],[11,1,1,"","get_data_size"],[11,1,1,"","get_hash"],[11,1,1,"","get_parts"],[11,1,1,"","get_progress"],[11,1,1,"","get_segments"],[11,1,1,"","get_transfer_size"],[11,1,1,"","is_compressed"]],"RNS.Reticulum":[[11,3,1,"","ANNOUNCE_CAP"],[11,3,1,"","DEFAULT_PER_HOP_TIMEOUT"],[11,3,1,"","LINK_MTU_DISCOVERY"],[11,3,1,"","MINIMUM_BITRATE"],[11,3,1,"","MTU"],[11,1,1,"","blackhole_sources"],[11,1,1,"","discovered_interfaces"],[11,1,1,"","get_first_hop_timeout"],[11,1,1,"","get_instance"],[11,1,1,"","get_lowest_interface_bitrate"],[11,1,1,"","get_medium_path_timeout"],[11,1,1,"","interface_discovery_sources"],[11,1,1,"","link_mtu_discovery"],[11,1,1,"","publish_blackhole_enabled"],[11,1,1,"","remote_management_enabled"],[11,1,1,"","required_discovery_value"],[11,1,1,"","should_use_implicit_proof"],[11,1,1,"","transport_enabled"]],"RNS.Transport":[[11,3,1,"","PATHFINDER_M"],[11,1,1,"","await_path"],[11,1,1,"","blackhole_identity"],[11,1,1,"","deregister_announce_handler"],[11,1,1,"","has_path"],[11,1,1,"","hops_to"],[11,1,1,"","next_hop"],[11,1,1,"","next_hop_interface"],[11,1,1,"","register_announce_handler"],[11,1,1,"","request_path"],[11,1,1,"","unblackhole_identity"]]},"objnames":{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","property","Python property"],"3":["py","attribute","Python attribute"]},"objtypes":{"0":"py:class","1":"py:method","2":"py:property","3":"py:attribute"},"terms":{"":[1,2,4,5,7,8,10,11,12,14,15,16,17],"0":[0,2,4,5,8,11,14,15,16],"00":[0,5,14,15],"000":0,"00000000":14,"0000001":0,"00000100":14,"00000111":14,"01":[5,14],"0100":5,"01010000":14,"02":4,"03":5,"04":5,"05":[0,2,5],"0536":15,"06":0,"06915":8,"06982":0,"08":[2,15],"09":[0,5],"097":0,"0d7334d411d00120cbad24edf355fdd2":5,"0f4259fef4521ab75a3409e353fe9073eb10783b4912a6a9937c57bf44a62c1":15,"0x0101":2,"0x20":2,"0x7d":2,"0x7e":2,"0x91c421ddfb8a30a49a71d63447ddb54cebe3465":13,"0xf000":[2,11],"1":[2,4,5,7,8,11,14,15,17],"10":[0,5,8,14,15],"100":[0,2,8,14],"1000":2,"10000000":14,"101":0,"102":0,"1024":[2,8],"103":0,"106":0,"107":0,"1081":0,"1087":0,"109":17,"11":[0,5,14],"110":0,"111":0,"1115":0,"1121":0,"115":14,"115200":[2,8,15],"1178a8f1fad405bf2ad153bf5036bdfd":15,"118":8,"12":[0,4,5,8,15],"1200":14,"122":0,"125":8,"125000":8,"1260p":0,"127":8,"128":[0,8,10,11,14],"13":[0,15],"132":0,"13425ec15b621c1d928589718000d814":[10,14],"1367":0,"137":0,"1373":0,"1381":0,"14":[5,8],"140":0,"144":0,"146":0,"1476":0,"149":0,"15":[0,5,8],"150":[8,15],"150m":8,"153cb870b4665b8c1c348896292b0bad":5,"15kb":17,"15m":15,"16":[0,5,8,10,14,15,17],"16190":0,"16192":0,"1625":8,"1625000":8,"167":14,"168":17,"17":[0,15],"1711":0,"1716230400":5,"1726dbad538775b5bf9b0ea25a4079c8":15,"175":0,"18":[0,5,15],"1800":11,"187":15,"1879":0,"188":0,"1884":0,"19":0,"192":17,"1976":0,"1980":0,"1984":0,"1985":0,"1989":0,"1990":0,"1991":0,"1992":0,"1997":0,"1998":0,"1999":0,"1a54d64db7e8beca6f2c6cd17b0cb479":5,"1b03013c25f1c2ca068a4f080b844a10":15,"1h":15,"2":[2,4,5,7,8,11,14,15],"20":[0,5,8,14,15],"200":[8,15],"2005":1,"2008":0,"201":8,"2010":0,"2016":[9,16],"2017":0,"2018":0,"2021":0,"2023":[0,4,15],"2024":5,"2025":[0,5],"2026":[0,5,9,17],"203":0,"21":[0,4],"21a8daa6d9c3d3b8aab6e94b6bcb0e33":5,"22":[0,5,8],"2225fdeecaf6e2db4556c3c2d7637294":15,"226":0,"229":0,"23":[0,5,15],"2316":15,"233":0,"236":0,"23h":15,"24":[5,8,15],"2400":12,"2400000000":8,"25":[0,2,7,16],"250":17,"252":0,"255":[8,15],"25519":11,"256":[0,5,8,10,11,14,15,16],"2592000":11,"26":0,"27":15,"280":0,"29":[0,8],"297":[14,16],"29716":8,"2b489d06eaf7c543808c76a5332a447d":15,"2b9ec651326d9bc274119054c70fb75":15,"2d":0,"2d03725b327348980d570f739a3a5708":15,"2d882c5586e548d79b5af27bca1776dc":15,"2f":2,"2owjajquafianpecac":4,"3":[0,2,4,5,8,12,14,15,16],"30":[0,5,8,11,15],"30602def3b3506a28ed33db6f60cc6c9":15,"31":0,"313":0,"32":[4,5,11,14],"3278":8,"327c1b2f87c9353e01769b01090b18f2":17,"32m":15,"33":[0,8],"34":[8,17],"340":0,"345":0,"35":0,"360":[5,8,11],"3600":[2,4,8],"37":[0,5],"374":0,"37428":15,"37429":15,"37k":0,"38":[0,5,15],"383":11,"3865":15,"399ea050ce0eed1816c300bcb0840938":15,"3a4f8b9c1d2e3f4g5h6i7j8k9l0m1n2o":15,"3b87":8,"3d":0,"3k":0,"4":[0,5,11,14,15],"40m":15,"42":[0,5],"420":0,"4242":[4,8],"4251":8,"42671":8,"430":14,"4343":8,"44":16,"44318":8,"45":[2,5,14],"46":15,"464":11,"465":14,"469":15,"471":0,"48":0,"48555":8,"49":[0,15],"490":0,"49555":8,"4965":15,"499":0,"4e":8,"4ed75ffdd":0,"4faf1b2e0a077e6a9d92fa051f256038":14,"4g":17,"4ghz":8,"4k":0,"5":[0,2,5,8,11,14,15,16,17],"500":[0,8,11,14,16,17],"5001":8,"501":0,"506":0,"508":0,"50824b711717f97c2fb1166ceddd5ea9":5,"51":[8,14],"512":[8,11,14,16],"519":0,"52":15,"521c87a83afb8f29e4455e77930b973b":15,"5233":0,"5245a8efe1788c6a1cd36144a270e13b":15,"53":[0,5],"535":0,"539":0,"54cc8d601":0,"55":8,"56":15,"5600x":0,"564":2,"566":0,"56m":15,"57":0,"5757":8,"58":0,"5858":8,"59":15,"593":0,"598":0,"5caf":8,"5d78":8,"5k":0,"5urvjicpzi7q3ybztsef4i5ow2aq4soktfj7zedz53s47r54jnqq":8,"6":[4,5,8,11,12,15],"60":[2,8,15],"600":[0,8],"629":0,"63":15,"636":0,"637":0,"64":[4,14,15],"65":0,"67":0,"687":0,"68a4aa91ac350c4087564e8a69f84e86":15,"69":0,"693":0,"7":[0,4,8,14,15],"709":0,"71":17,"71e5":8,"72":8,"720":[8,11],"7200":8,"73":[8,15],"730":0,"737":0,"73cbd378bb0286ed11a707c13447bb1":15,"74":15,"74195":8,"74bea355":0,"781":15,"7822":15,"7a55144adf826958a9529a3bcf08b149":15,"8":[0,2,8,15],"80":[13,15],"800":0,"8001":8,"805":0,"809":15,"82":0,"83":[14,15],"83b7328926fed0d2e6a10a7671f9e237":17,"84":0,"84fpy1qbxhcgdseepynmhthcrgmx4nffbytz2gkytoqhvvhjp8eaw1z1eedrnkd19b3b8nilcgvxzkv17ummmeescrpya5w":13,"86":15,"86240b027":0,"865":8,"865600000":8,"867":8,"867200000":8,"868":14,"88":[0,8],"886":0,"89":[0,8],"8a37cdd16938ce79861561adbd59023a":5,"8dd57a738226809646089335a6b03695":15,"8f3a21c9d84e927b":5,"8f7e6d5":5,"8f7e6d5c8f7e6d5c8f7e6d5c8f7e6d5c8f7e6d5":5,"8k":0,"9":[0,4,5,15],"90":5,"900":[0,14,15],"9037":15,"921600":15,"928":0,"94":0,"940":0,"941bed5e228775e5a8079fc38b1ccf3f":15,"959e10e5efc1bd9d97a4083babe51dea":5,"96":[0,14],"9600":2,"9710b86":5,"9710b86ba12c42d1d8f30f74fe509286":5,"9710b86ba12c4f2":5,"982":0,"983":0,"984b74a3f768bef236af4371e6f248cd":15,"99":[0,14],"99714":8,"9a":5,"9d27af75c":0,"9fb6d773498fb3feda407ed8ef2c3229":15,"9h":15,"9k":0,"9th":0,"A":[1,2,4,5,7,8,9,10,11,12,14,15],"AND":9,"AS":9,"And":[1,2,7,17],"As":[0,1,4,5,6,8,11,12,13,14,15,16],"At":[0,4,14],"BE":9,"BUT":9,"Be":[0,5,11,15,17],"Being":0,"But":[1,7,13,14,17],"By":[1,2,4,5,7,8,11,14,15,17],"FOR":9,"For":[1,4,5,7,8,10,11,12,14,15,16],"IN":[2,9,11],"If":[0,1,2,4,5,6,8,10,11,12,13,14,15,16,17],"In":[1,2,4,5,6,7,8,10,11,12,14,15,16],"It":[0,1,2,4,5,6,8,10,11,12,14,15,16,17],"Its":0,"NO":9,"NOT":9,"No":[2,4,7,8,10,14,15,16,17],"Not":7,"OF":9,"OR":9,"Of":[10,14],"On":[1,2,4,5,7,8,10,15,17],"One":[0,4,5,6,8,11,14,17],"Or":[5,7,8,14,15,16],"Such":[0,1,8],"THE":9,"TO":9,"That":[1,5,7,12,14,17],"The":[2,4,6,7,8,9,10,11,12,13,16],"Their":0,"Then":[0,1,2,4],"There":[0,1,4,10,14,15,17],"These":[1,4,5,7,8,10,11,12,14,15],"To":[2,4,5,6,7,8,10,14,15,16],"WITH":9,"Will":11,"With":[1,7,8,10,12,14,15,17],"_":14,"__":14,"______":14,"_______":14,"________":14,"________________":14,"__future__":2,"__init__":[2,11],"__main__":2,"__name__":2,"__str__":2,"_no_us":11,"a010e6613":0,"a1b2c3d4e5f686ba12c42d1ba12ef1aa":5,"a4d":8,"a79f":8,"aarch64":[0,4],"ab":2,"abandon":[0,1],"abc":5,"abil":[0,1,4,5,6,7,9,15,16],"abl":[0,1,2,4,5,8,11,14,15],"abolish":17,"abort":[1,2,5,8],"about":[0,2,4,5,6,8,10,11,14,15,17],"abov":[0,4,5,6,8,9,14,15],"abridg":0,"absenc":0,"absent":0,"absolut":[0,8,13,16,17],"abstract":[0,10,11,14,17],"abstractmethod":11,"absurd":0,"abund":[6,17],"abus":[0,15],"academ":1,"acceler":0,"accept":[0,1,5,8,11,13,14,15,17],"accept_al":[2,11],"accept_app":11,"accept_non":11,"accepts_link":11,"access":[0,1,4,7,8,10,11,15,17],"access_point":[8,10],"accid":[0,12,17],"accommod":[11,14],"accomod":17,"accompani":0,"accord":[0,2,4,5,10,14],"accordingli":[2,8],"account":[0,1,10,11,17],"accumul":0,"accus":0,"achiev":[0,1,4,8,10,11,14,16],"acknowledg":[0,10,16],"acquir":0,"across":[0,1,2,5,6,8,10,11,14,15,17],"act":[0,1,4,8,11,14,15,17],"action":[0,1,2,9,15],"activ":[0,1,2,4,5,8,11,12,14,15],"actor":[1,14,15,17],"actual":[1,2,4,5,7,8,10,14,15,17],"ad":[0,1,2,5,6,7,8,10,11,12,14,15,16,17],"adapt":[0,4,6,17],"add":[0,1,2,4,5,8,10,11,15],"add_argu":2,"add_message_handl":[2,11],"add_ready_callback":11,"addendum":7,"addict":17,"addit":[0,5,6,8,10,11,12,14,15,16],"addition":[4,5,6,8,14],"addr":15,"address":[0,1,2,4,5,7,8,11,14,15,16],"adher":[8,11],"adjust":[0,4,5,11,15,17],"adm":5,"admin":[5,8],"administ":[0,5],"administr":[0,5,7,10,14,15,17],"admit":0,"adopt":[0,14],"adress":[11,14],"advanc":[0,12,14],"advantag":11,"advers":16,"adversari":[0,4,10,13,17],"advertis":[0,2,8,11],"advic":[0,13],"advis":[8,14],"ae":[0,11,14,16],"aetherlab":12,"af73":8,"aff":0,"affair":0,"affect":[0,4,8,17],"affili":1,"affin":8,"affirm":0,"afford":10,"after":[0,2,4,5,8,10,11,14,15],"afterthought":[0,17],"ag":[0,1],"again":[0,8,14,15],"against":[0,1,4,5,8,14,17],"agenc":[7,14],"agenda":0,"agent":[7,14,17],"aggress":0,"agnost":[10,14],"agnostic":[14,17],"ago":[0,15],"agpl":0,"agreement":[0,1,17],"ahead":[0,10],"ai":[0,17],"aim":[0,1,4,7,12,14],"air":[4,6],"airmax":6,"airtim":[0,8,10,17],"airtime_limit_long":8,"airtime_limit_short":8,"airwav":0,"akin":14,"alexand":0,"algorithm":[0,1,9,10,17],"alia":5,"alias":7,"aliased_nam":5,"alic":[5,14],"alien":17,"align":[0,4,15,17],"aliv":[11,14],"all":[0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17],"allerg":0,"allevi":6,"alloc":[0,8,10,11,14,15],"allow":[0,1,2,4,5,6,8,10,11,12,14,15,16,17],"allow_al":[2,11],"allow_list":11,"allow_non":11,"allowed_hash":15,"allowed_ident":15,"allowed_list":11,"allowedsignersfil":5,"almost":[0,1,6,8,14,15,17],"alon":[0,8],"along":[5,8,11,14,15],"alongsid":[5,10],"alpha":12,"alreadi":[0,2,4,5,6,10,11,12,14,15,17],"also":[0,1,2,4,5,6,7,8,10,11,12,14,15,16,17],"altai":0,"alter":[4,11,14],"altern":[0,2,4,5,8,15],"although":[4,14,16],"altitud":8,"alwai":[0,1,4,5,8,10,11,14,15,17],"am":17,"amateur":[8,16],"ambigu":0,"amd64":0,"america":0,"among":[1,17],"amongst":[0,9],"amount":[0,2,8,10,11,14,16,17],"amplifi":1,"amsterdam":[8,15],"an":[0,1,2,4,5,6,8,9,10,11,12,14,15,16,17],"analog":[12,17],"analysi":[1,5,7],"analyt":13,"analyz":[0,1],"ancestri":0,"anchor":7,"andi":0,"android":[7,8,12,15],"ani":[0,1,2,4,5,6,8,9,10,11,12,13,14,15,16],"annonuc":8,"annot":2,"annouce_cap":8,"announc":[0,4,5,7,10,11,15],"announce_cap":[8,11],"announce_handl":2,"announce_interv":[5,8],"announce_packet_hash":11,"announce_rate_grac":[4,8],"announce_rate_penalti":[4,8],"announce_rate_target":[4,8],"announced_ident":[2,11],"announceloop":2,"announces_from_intern":8,"announces_to_intern":8,"announcesampl":2,"annoy":15,"anonym":[0,4,10,11,14,16],"anoth":[0,5,8,10,11,14,15,17],"answer":[14,15,17],"antenna":[0,6,17],"anticip":[0,5],"antidot":0,"anxieti":17,"anymor":[4,17],"anyon":[0,1,2,4,5,6,8,10,11,14,15,17],"anyth":[0,1,5,6,8,12,14,15,16,17],"anywai":[0,8],"anywher":[0,1,2,8,17],"ap":8,"apach":0,"api":[4,5,7,14,16,17],"apk":4,"app":[0,2,4,11,12,14,17],"app_and_aspects_from_nam":11,"app_data":[2,11],"app_nam":[2,11],"app_timeout":2,"appar":[0,1],"apparatu":0,"appeal":0,"appear":[0,17],"append":[2,14,15],"appl":0,"appli":[0,1,5,8,11,14,17],"applic":[0,1,2,8,10,11,12,14,15,16,17],"appreci":5,"approach":[0,1,4,6,10,14,15],"appropri":[0,1,5,8,10,17],"approv":[0,1,10,14,17],"approxim":[0,8,15],"april":[0,4],"apt":4,"ar":[1,2,4,5,6,7,8,10,11,12,13,14,15,16,17],"arbit":17,"arbitrari":[5,11,14,15,16],"arch":[0,4,17],"architect":[13,17],"architectur":[0,4,7,12],"archiv":[0,5,7,12],"area":[1,4,6,8,10,14,16],"arg":[2,15],"argon":2,"argpars":2,"argument":[2,5,7,11,15],"argumentpars":2,"aris":9,"arithmet":0,"arm":0,"arm64":7,"armi":17,"armor":[5,17],"around":[0,4,8,14,17],"arrai":[0,4],"arrang":[0,1],"arriv":[0,2,8,14,17],"art":[0,17],"articl":0,"artifact":[0,5,7],"artifacts_dir":5,"artifex":0,"artifici":[0,9],"artist":0,"arx":15,"ascii":5,"ask":[0,2,4,6,11,12,17],"aspect":[2,4,6,8,10,11,14,15],"aspect_filt":[2,11],"aspir":0,"assembl":0,"assent":0,"assert":[0,1,17],"assess":0,"assign":[0,2,10,14,15,17],"assist":[7,12],"associ":[0,5,9,11,14,15],"assum":[0,8,10,14,17],"assumpt":[0,10,13,17],"assuredli":17,"asymmetr":[14,15,16],"asymmetri":[0,1],"asynchron":[10,17],"atop":1,"atrophi":0,"attach":[0,1,12,15],"attached_interfac":11,"attack":[0,4],"attain":[0,4],"attempt":[0,2,4,5,6,8,11,15],"attend":0,"attent":[0,1,13,17],"attest":[0,5],"attract":0,"attribut":[1,7,11],"atx":15,"audienc":0,"audio":12,"audit":0,"auth":15,"authent":[1,5,8,10,11,12,14,15,16],"author":[1,7,9,14,15,17],"authoris":[0,15],"authorit":[0,5,14,16],"authorship":[0,1],"auto":[4,5,6,7,11,14,15],"auto_compress":11,"autoconfigur":16,"autoconnect_announces_to_intern":15,"autoconnect_discovered_interfac":[8,15],"autoconnect_interface_grav":8,"autoconnect_interface_mod":15,"autoconnect_unverified_implement":15,"autodiscov":8,"autoinstal":[6,15],"autointerfac":[4,6,8,15],"autom":[0,1,4,5,6,7,12,13,14],"automat":[2,4,7,8,10,11,12,14,15,16,17],"autonom":[1,10,14,17],"autonomi":[1,16,17],"avail":[0,1,2,4,5,6,7,8,10,11,12,14,15,16,17],"avatar":0,"averag":14,"avoid":[6,14,15],"awai":[0,1,2,8,14,15,17],"await_path":11,"awar":[0,4,5,8,14],"ax":[7,16],"ax25kissinterfac":8,"axiom":0,"b":[0,2,5,15],"b32":8,"back":[0,1,2,5,8,14,16,17],"backbon":[0,6,7,10,15,17],"backboneinterfac":[0,4,8,15],"backend":[8,14],"background":[4,8,15],"backhaul":[6,10],"backup":[1,15],"backward":0,"bad":0,"badg":0,"badli":0,"baker":0,"balanc":[0,8],"ban":0,"banal":0,"band":[6,14,17],"bandwidth":[0,4,7,8,10,11,12,14,15,16],"bar":[0,17],"bare":[0,1,2,5,8,17],"barrier":[1,8,14,17],"base":[0,1,5,7,8,10,11,12,14,15,16,17],"base32":[8,15],"base64":[5,15],"baselin":0,"bash":[8,15],"bash_sourc":5,"basi":[0,1,8,11,14,15,16],"basic":[0,2,4,7,8,10,11,12,15],"batch":5,"batter":0,"batteri":17,"baud":[8,15],"baud_flash":15,"baudrat":2,"bc1pgqgu8h8xvj4jtafslq396v7ju7hkgymyrzyqft4llfslz5vp99psqfk3a6":13,"bc7291552be7a58f361522990465165c":[15,16],"beacon":8,"bear":0,"beast":17,"beat":17,"beauti":[1,12],"becam":[0,1],"becaus":[0,1,5,10,14,17],"becki":2,"becom":[0,1,2,4,5,8,10,14,17],"bedrock":0,"been":[0,1,2,4,5,6,8,10,11,12,13,14,15,16,17],"befor":[0,2,4,5,8,10,11,13,14,15,17],"beg":17,"begin":[0,2,6,11,17],"begun":[0,11],"behalf":[8,10],"behav":[0,6,12],"behavior":[0,8,12,17],"behaviour":[0,4,8,15],"behind":[0,4,8,13,14,17],"being":[0,1,4,5,8,11,12,14,17],"beings":[0,1,9,14],"belief":[0,14],"believ":[0,1,17],"belong":[0,8,10,14,15,17],"below":[0,6,8,15],"benchmark":0,"bend":17,"benefici":[8,15],"beneficiari":0,"berlin":17,"besid":0,"best":[0,4,10,11,14,17],"beta":0,"better":[0,1,4,8,10,13,14,17],"between":[0,1,2,8,10,11,12,14,15,17],"beyond":[0,1,5],"bi":[11,14],"bicker":0,"bidirect":14,"big":17,"bill":17,"billion":[10,14],"billionair":17,"bin":[4,8,15],"binari":[0,2,4,8,10,11,14,15,17],"bind":[0,7,8],"bio":0,"bit":[0,2,4,5,8,10,11,12,14,15,16,17],"bitcoin":13,"bitrat":[2,8,11,12],"bizarr":0,"black":1,"blackhol":[4,7,10,11,14],"blackhole_ident":11,"blackhole_sourc":[11,15],"blackhole_update_interv":15,"blackholed_ident":15,"blackholeupdat":15,"blatant":0,"ble":8,"bless":0,"blindli":[0,15,17],"blizzard":0,"blob":[2,5,14],"block":[0,4,5,7,10,11,12,14,15,17],"block_fast_flap":8,"blockchain":17,"blocklist":15,"blog":0,"blood":17,"blueprint":17,"bluetooth":15,"board":[0,4,7,8,12,14,16],"boat":17,"bob":5,"bobs_nod":5,"bodi":0,"bogu":8,"boil":6,"bond":17,"book":[0,12,17],"bookworm":7,"bool":11,"boot":[4,15],"bootstrap":[7,8,15],"bootstrap_onli":[4,8],"borrow":17,"bot":12,"both":[0,1,2,4,5,6,8,10,11,12,14,15,16],"bother":0,"bottl":0,"bounc":[4,17],"bound":[7,10,17],"boundari":[0,1,5,8,10,14],"box":[1,6],"brain":0,"branch":[1,5,15],"brandolini":7,"breach":0,"breadcrumb":5,"breadth":0,"break":[0,4,11,14,17],"breath":[0,4,17],"breviti":15,"bridg":[6,8],"brief":7,"briefli":[0,6,14],"brillianc":0,"bring":[0,8,15],"brittl":[4,17],"broad":[4,6],"broadcast":[0,4,7,8,10,11,12,14,15,17],"broadcast_destin":2,"broadcastloop":2,"broader":[0,4,14],"broken":[0,4,8,15,17],"brought":[0,8,15],"brows":[1,5,7,17],"browser":[0,5,7,17],"buffer":[7,8,11,16],"bufferedread":11,"bufferedrwpair":11,"bufferedwrit":11,"bufferexampl":2,"bug":[0,5,12,13],"bui":17,"build":[0,1,2,5,6,7,8,12,14,16,17],"builder":[0,17],"built":[0,1,4,8,10,12,14,15,16,17],"bulletin":12,"bulli":0,"bullshit":0,"bundl":[0,2],"bureaucraci":17,"bureaucrat":[16,17],"burgundi":0,"buri":0,"burrow":0,"burst":[7,15],"busiest":0,"busy":1,"butlerian":0,"button":[0,17],"bw":15,"bypass":[0,8,13,17],"byte":[0,2,7,10,11,14,15,16],"bytes":2,"c":[0,2,5,9,15],"c50cc4e4f7838b6c31f60ab9032cbc62":15,"c89b4da064bf66d280f0e4d8abfd9806":15,"ca":0,"cabl":[8,12,17],"cach":[8,10,15],"cadenc":0,"cafe":17,"cage":17,"cal":0,"calcul":[10,11,14,15],"calibr":0,"call":[0,1,2,10,11,12,14,16,17],"callabl":[2,11],"callback":[2,11],"callsign":8,"calm":0,"calmli":0,"cambrian":0,"came":[0,5],"camp":1,"campaign":0,"can":[0,1,2,4,5,6,7,8,10,11,12,13,14,15,17],"cancel":[0,5,11],"candid":[0,10],"cannot":[0,1,2,4,5,8,10,16,17],"canon":0,"cap":8,"capabl":[0,1,2,4,8,10,12,14],"capac":[0,4,6,10,11,14],"capit":[1,17],"captur":[0,1,17],"car":10,"carambola":2,"card":[1,12,17],"care":[0,1,4,5,10,11,15,16,17],"carefulli":[0,4],"cargo_build_target":4,"caricatur":0,"carri":[0,1,8,10,11,14,15,16,17],"carrier":[7,10,16],"cascad":0,"case":[1,2,4,5,6,7,8,10,12,14,15],"cast":0,"castl":17,"casual":0,"cat":15,"catalogu":0,"catastroph":[0,1],"categori":[0,6],"catiou":0,"caught":0,"caus":[0,4,8],"caution":8,"cb":[11,14],"cbc":[14,16],"cc4d524a3":0,"cd":5,"cdma":8,"ceas":[0,1,17],"cede":1,"cell":[0,10],"cellular":17,"cement":17,"censor":[1,14,15,17],"censorship":[14,16],"center":[0,7],"centr":0,"central":[0,1,4,5,6,8,10,12,14,15,17],"centralis":14,"centric":1,"centuri":1,"ceo":17,"certain":[0,2,8,10,14,15,17],"certainti":0,"certif":[0,17],"certifi":[0,1],"cetera":0,"chain":[0,5,8,17],"challeng":[0,4,12,14,17],"chanc":6,"chang":[0,1,2,4,5,8,11,14,15,16,17],"channel":[0,1,4,5,7,8,10,11,13,14,16,17],"channelarg":2,"channelexampl":2,"chaotic":17,"chapter":[0,1,4,5,6,8,10,11,12,14,15,16],"charact":[0,2,5,8,15],"characteris":0,"characterist":[0,8,10,14,17],"charad":0,"charg":[0,9],"chart":[0,5],"charter":14,"chase":17,"chat":7,"cheap":[0,6,8,14],"cheaper":0,"cheapli":4,"check":[0,2,4,5,11,12,14,15,17],"checksum":[5,11,16],"chmod":5,"choic":[0,4,10,17],"choke":17,"choos":[0,1,2,4,8,12,14,17],"choreographi":0,"choru":0,"chose":[0,14],"chosen":14,"chunk":2,"churn":0,"ci":0,"cific":8,"ciphertext":11,"ciphertext_token":11,"cir":0,"circl":17,"circuit":0,"circul":0,"circumst":[13,14,17],"citat":0,"cite":0,"citi":[0,17],"cl":2,"claim":[5,7,9,14],"claimant":0,"clariti":17,"class":[0,2,10,11,16],"classifi":0,"claud":0,"clean":7,"cleanest":0,"clear":[0,2,8,11,15,17],"clear_default_app_data":11,"clear_screen":2,"clearer":0,"clearli":[0,17],"click":5,"client":[1,2,5,6,7,11,12,15,17],"client_buffer_readi":2,"client_config":5,"client_connect":2,"client_disconnect":2,"client_ident":[2,5],"client_loop":2,"client_message_receiv":2,"client_packet_receiv":2,"client_request":2,"climat":17,"clone":[0,5,14],"close":[0,2,10,11,15],"closed_callback":11,"closer":[12,14],"closest":14,"closur":0,"cloth":17,"cloud":[1,7,8,12],"cluster":[1,14],"co":[0,5,6,8,16],"code":[1,4,5,6,7,8,10,12,13,15,16,17],"codebas":0,"codens":0,"codex":0,"codic":1,"codifi":0,"codingr":8,"coexist":[7,10],"coffe":17,"coher":17,"coin":0,"collabor":[1,5,12,14,15],"collaps":[0,1,4,17],"collect":[0,1,4,13],"collis":10,"colon":17,"color":5,"columba":7,"columbia":0,"com":[0,2,5,13,17],"combin":[0,1,4,5,7,12,14,15,17],"combinatori":17,"come":[0,1,4,8,10,14,15,17],"comma":[8,15],"command":[0,1,2,4,7,8,12,15],"commend":17,"commensur":0,"comment":[0,1,5,8,15],"commentari":0,"commerci":[0,17],"commiss":0,"commit":[0,1,4,7,12],"committ":0,"committe":[0,17],"common":[1,2,4,6,7,10,14,15,16,17],"commonli":[0,5,6,8],"commun":[0,1,2,4,5,7,8,10,11,12,13,14,15,16,17],"communica":8,"compani":17,"companion":[0,12],"compar":[10,17],"comparison":0,"compass":17,"compat":[0,1,2,4,5,6,8,11,12,14,15,16],"compet":[0,1,17],"compil":[0,4],"compiled_refer":0,"complain":17,"complaint":0,"complement":0,"complet":[0,1,2,4,5,6,8,10,11,12,14,15,16],"complex":[0,1,4,8,13,14,17],"compli":10,"complianc":0,"compon":[6,7,13,14,17],"compos":[0,5,7,14],"comprehens":[1,12,13],"compress":[2,11,14,15,16],"compromis":[1,14,17],"comput":[0,1,4,8,14,16,17],"computation":[8,15],"concaten":[11,15],"conceal":0,"conceiv":[0,1,4,6],"concept":[0,1,7,14,15,17],"conceptu":[0,1,5,7],"concern":[0,17],"concert":14,"concis":0,"conclud":[0,2,11],"conclus":7,"concret":[0,17],"concurr":[6,14,15],"condens":0,"condit":[4,7,9,14,16,17],"conduct":[0,1],"conduit":17,"conf":[4,12],"confer":0,"confess":0,"confid":0,"config":[2,4,5,8,10,15,17],"configarg":2,"configdir":11,"configobj":5,"configpath":2,"configur":[0,1,2,4,6,7,10,11,12,14,16],"configuraion":6,"configuraiton":15,"configure_devic":2,"confirm":[5,10,14,16,17],"conflict":[4,10],"conform":[1,7],"confront":17,"confus":[0,6,14],"congest":14,"conglomer":17,"conjunct":8,"connect":[0,1,2,5,6,7,9,11,13,14,15,16,17],"conscienc":17,"consciou":0,"conscious":[0,1],"conscript":17,"consent":1,"consequ":[1,7,10,14],"conserv":[0,8],"consid":[0,2,4,8,11,12,14,15,16,17],"consider":[0,7,14],"consist":[0,5,14,15],"consol":15,"constant":[1,11,17],"constantli":[14,17],"constitu":0,"constitut":[0,1,4,14],"constrain":[10,11],"constraint":[0,17],"construct":[0,1,5,14,16,17],"constructor":2,"consult":0,"consum":[0,5,10,11,17],"consumpt":[10,17],"contact":[0,8,10,12,14,17],"contain":[0,1,2,5,8,10,11,14,15],"contamin":0,"contempl":17,"contemporari":1,"contend":14,"content":[0,1,2,4,5,10,15],"contest":0,"context":[4,7,14,15,17],"contin":[2,4,17],"continu":[0,1,5,8,11,13,15,16,17],"contract":[0,9],"contractu":0,"contradict":0,"contrari":[0,17],"contrast":[0,1],"contribut":[0,1,7,9,10,13],"contributor":[0,1],"control":[0,1,2,4,5,6,7,10,11,12,14,15,16,17],"controversi":0,"convei":[0,2,17],"conveni":[0,1,2,5,15,17],"convent":[0,2,10],"converg":[4,10,14,17],"convers":[0,1,5,12,14,17],"convert":[0,1,5],"convinc":0,"convincingli":0,"cook":4,"coordin":[0,8,10,11,14,16,17],"copi":[1,5,7,9,15],"copier":0,"copilot":0,"copyleft":0,"copyright":[1,7,9],"core":[0,1,10,14,15,16,17],"corner":17,"corollari":0,"corp":0,"corpor":[0,1,17],"corpu":0,"correct":[0,1,2,5,8,10,14],"correctli":[0,2,5,10],"correspond":[5,10,14,17],"corrobor":0,"corrupt":[1,5],"cosmologi":0,"cost":[0,6,7,8,14,16],"costum":0,"could":[0,1,2,4,8,10,11,14,15,16,17],"counsel":0,"count":[0,5,12,14,17],"counter":2,"coupl":0,"courier":0,"couriership":0,"cours":[0,4,5,8,10,14,17],"court":0,"coven":[0,17],"cover":[0,4,5,6,10,11,14,16],"coverag":[8,10],"cp313":0,"cpp":0,"cpu":[0,2,8,10,14],"cpuinfo":15,"cpython":0,"cr":15,"craft":[0,1,5,17],"craftsman":17,"crash":17,"crate":0,"creat":[0,1,2,7,8,10,11,12,15,16,17],"create_bidirectional_buff":[2,11],"create_kei":11,"create_read":11,"create_receipt":[2,11],"create_writ":11,"creation":[0,1,7,9,10,12,14,15,16],"creativ":[0,1,17],"creator":[0,1,7,14,17],"credenti":[8,14],"credit":0,"crippl":0,"crisi":0,"criteria":0,"criterion":0,"critic":[0,1,10,14,15],"crn":0,"cron":1,"cross":[0,8,12],"crowd":17,"crucial":10,"cruft":17,"crypto":0,"cryptograph":[0,1,4,7,8,10,15,16,17],"cryptographi":[1,4,14,16],"crystal":17,"ctrl":2,"cull":11,"culmin":17,"cultur":[0,1],"cumbersom":5,"curl":8,"currenc":0,"current":[0,1,2,4,5,7,8,11,12,15,17],"current_download":2,"current_filenam":2,"current_ratchet_id":11,"cursor":0,"curtain":0,"curv":[10,11,14,16],"curve25519":[10,11,14,16],"custodian":17,"custom":[0,6,7,11,12,14,16],"custom_network_nam":8,"customis":8,"cut":[0,17],"cv":0,"cycl":0,"cynic":17,"cython":0,"d":[0,5,15],"d09285e660cfe27cee6d9a0beb58b7e0":5,"d56a4fa02c0a77b3575935aedd90bdb2":15,"daemon":[0,2,4,8,11,12,15],"dai":[0,5,11,12,17],"daili":[0,5],"damag":[0,1,9,17],"damn":0,"danc":17,"dang":0,"danger":[0,17],"dark":17,"darwin":0,"data":[0,1,2,4,5,6,7,8,10,11,14,16,17],"data_buff":2,"data_port":8,"databas":[1,12,15,17],"databit":[2,8,15],"datacent":4,"datar":8,"dataset":[0,9,17],"date":[2,4,5,7,15],"datetim":2,"dawn":0,"db":[2,15],"dbm":[2,8,15],"dead":0,"deadlin":1,"deal":[0,8,9],"dealt":0,"death":[0,7],"deb":0,"debas":0,"debat":0,"debian":[0,7,14,15],"debug":[0,4,15],"decad":[0,1,6,13,17],"deceiv":0,"decentr":[4,7,8,15],"decentralis":16,"decept":0,"decid":[0,1,8,10,11,14,17],"decim":8,"decis":[0,1,5,8,10,14,17],"declar":[0,14],"declin":0,"decod":[0,2,8,15],"decor":0,"decoupl":1,"decreas":[5,8,15],"decrypt":[0,8,10,11,14,15],"dedic":[0,5,8,14,16,17],"dedupl":0,"deed":0,"deep":[0,4,17],"deeper":0,"deepli":[0,1,17],"deepseek":0,"def":[2,5],"default":[0,2,4,5,6,8,10,11,12,14,15],"default_ar_grac":8,"default_ar_penalti":8,"default_ar_target":8,"default_grav":8,"default_ifac_s":2,"default_per_hop_timeout":11,"defenc":7,"defenceless":0,"defend":0,"defens":0,"defin":[0,2,5,8,11,14,15,16,17],"definit":[0,2,4,5,14,15,17],"deflect":0,"defunct":[0,15],"degrad":[0,10],"degre":[0,8],"delai":[8,12,14,15,17],"deleg":[1,5,14],"delet":[0,1,5,17],"deliber":0,"delimit":2,"deliv":[0,2,4,10,11,12,17],"deliveri":[0,1,2,5,10,11,12,16],"delus":7,"delusion":0,"demand":[0,5,11,17],"demonstr":[0,1,2,4,8,17],"deni":[1,5,17],"denomin":[0,1],"densiti":0,"depend":[0,1,2,5,6,7,8,10,11,14,15,17],"depict":0,"deploi":[0,14,17],"deploy":[0,5],"deprec":0,"depriorit":17,"depth":[0,17],"derail":0,"deregist":11,"deregister_announce_handl":11,"deregister_request_handl":11,"deriv":[0,4,10,11,14,16],"descend":0,"describ":[0,5,6,8,11,14],"descript":[0,2,5,15],"descriptor":2,"deseri":2,"deserializ":2,"deserv":0,"design":[0,1,4,5,6,7,8,10,12,13,14,15,16],"desir":[0,2,6,8,14],"desk":17,"desktop":[8,12],"dest_len":2,"destin":[0,2,4,7,11,15,17],"destination_1":2,"destination_2":2,"destination_clos":2,"destination_hash":[2,5,11,15],"destination_hexhash":2,"destroi":[1,17],"destruct":[0,17],"detach":[5,8,15],"detail":[0,1,2,4,5,7,8,11,15,16],"detect":[0,2,5],"deterior":0,"determin":[0,4,10,11,14,17],"determinist":5,"detriment":15,"dev":[2,4,5,8,15],"devalu":0,"devel":4,"develop":[0,5,6,7,9,11,12,13,14,15,16,17],"deviant":0,"devic":[0,2,4,7,8,10,11,14,15,17],"dfsg":0,"dh":11,"dhcp":[6,8,10,15],"di":17,"diagnosi":0,"dial":[0,12],"diametr":0,"dichotomi":7,"dict":2,"dictat":[15,17],"dictatori":0,"dictatorship":[0,17],"dictionari":15,"did":[0,1,2,12,17],"didn":0,"diff":5,"differ":[0,1,2,4,5,6,8,10,11,12,14,15,16,17],"differenti":15,"diffi":[10,14],"difficult":[0,4,6,15],"difficulti":[8,15],"digit":[1,4,6,14,16,17],"digniti":[0,1,17],"dilut":1,"dimens":0,"dinner":17,"dipol":0,"dir":[2,5],"dire":6,"direct":[0,1,2,4,5,6,10,11,12,14,15],"direction":[0,14],"directli":[1,4,5,6,7,8,9,10,11,12,14,15,16,17],"directori":[2,4,5,8,10,15,17],"dirnam":5,"dirt":0,"dirti":0,"dirtiest":0,"disabl":[8,14,15],"disadvantag":0,"disagre":0,"disappear":[8,15,17],"disassoci":14,"discard":[4,11,14],"discern":[0,1],"disciplin":[0,1,17],"disclos":7,"disclosur":0,"disconnect":[2,4,7,8],"discourag":1,"discov":[0,1,4,7,8,10,11,14,17],"discover":[4,7,15],"discover_interfac":15,"discovered_interfac":11,"discoveri":[0,4,5,7,11,12,14,15],"discovery_bandwidth":8,"discovery_encrypt":8,"discovery_frequ":8,"discovery_lxmf_address":8,"discovery_modul":8,"discovery_nam":8,"discovery_port":8,"discovery_scop":8,"discovery_stamp_valu":8,"discret":1,"discrimin":[0,10],"discuss":[0,1,5,6,14],"disk":[2,5,11,15],"dismiss":0,"displai":[2,5,8,10,12,14,15],"disproven":0,"disput":0,"disqualifi":0,"disregard":0,"disrupt":[1,8],"dissemin":1,"dissent":0,"dissip":0,"dissolv":[10,17],"dissuad":0,"dissuas":0,"dist":5,"distanc":[6,14,15],"distant":[4,11,14],"distinct":[0,1,8,10,14,17],"distinguish":[0,10,14],"distribut":[2,5,7,9,10,11,12,14,15,16,17],"district":0,"dive":4,"diverg":[0,1],"divers":[0,1],"divid":11,"divmod":2,"dn":[6,8,12,17],"dna":17,"dnf":4,"do":[1,2,4,5,6,7,8,9,10,11,14,15,17],"doc":0,"doc_id":5,"doctrin":0,"document":[0,1,4,7,9,11,12,14,15,16,17],"doe":[1,2,4,5,6,7,8,11,12,14,15,17],"doer":0,"doesn":[1,8,10,17],"dollar":[0,17],"domain":[0,1,4,7,8,14,15,16],"domin":17,"don":[0,2,4,5,10,11,14,15,17],"donat":[0,7],"done":[0,2,4,5,8,14,15,17],"door":[0,17],"dot":[14,15],"doubt":[0,4],"dowload":4,"down":[0,1,2,6,8,11,12,15,17],"download":[1,2,4,5,8,10,15],"download_began":2,"download_conclud":2,"download_finish":2,"download_start":2,"download_tim":2,"downstream":[0,15],"dozen":7,"draft":0,"drag":[0,12],"drain":[0,8],"dramat":0,"drastic":15,"draught":0,"draw":[0,17],"drawn":[0,17],"dress":0,"drift":0,"drink":0,"drive":[1,13],"driver":[15,16],"droid":4,"drone":17,"drop":[0,5,8,10,11,12,14,15,17],"drown":1,"dsrdtr":2,"dual":[0,6,15],"dualiti":0,"dublin":15,"due":[1,2],"dumb":17,"dump":[8,15],"duplex":[14,16],"durabl":[0,1],"durat":15,"dure":[0,5,15],"duti":0,"dynam":[1,4,5,8,12,15,17],"dysfunct":13,"dysregul":1,"e":[2,5,12,15],"e5c032d3ec4e64a6aca9927ba8ab73336780f6d71790":15,"e702c42ba8":15,"e7536ee90bd4a440e130490b87a25124":15,"each":[0,1,2,4,5,8,10,11,12,14,15],"earli":[0,12,17],"earlier":[0,14],"earliest":0,"earn":0,"earth":0,"eas":[8,12,14],"easi":[0,4,5,6,8,12,14,15,16],"easier":[0,4,5,8,10,15,16],"easiest":[4,6,8,14],"easili":[0,1,4,5,8,10,14,15,16,17],"eastern":14,"eaten":0,"ec_pr_freq":8,"ecdh":[14,16],"echo":[0,5,7],"echo_destin":2,"echo_request":2,"econom":1,"economi":17,"ecosystem":[0,1,4,8,12,14,15,17],"ed25519":[1,5,14,16],"edd8e72b":0,"edg":0,"edit":[0,4,5,15],"editor":[5,15],"editori":0,"educ":0,"ee":5,"eeprom":15,"effect":[0,1,5,8,14,15],"effici":[0,2,4,8,10,11,12,14,15,16,17],"effort":[0,6,11,17],"effortless":0,"effortlessli":12,"eg":15,"egress":8,"egress_control":8,"ei":2,"eight":0,"either":[0,4,5,6,10,11,14,15,17],"elaps":[5,8],"electromagnet":17,"eleg":17,"element":[0,10,17],"elev":1,"elif":2,"elig":0,"elimin":[1,10,17],"ellipsoid":8,"ellipt":[10,11,14,16],"elong":7,"els":[0,1,2,10,12,13,14,16,17],"elsewher":0,"email":[1,5,12],"emb":5,"embed":[0,1,5,6,12],"embellish":0,"embodi":0,"embrac":17,"emerg":[1,7,12],"emiss":12,"emot":1,"empir":0,"emploi":[0,1,6,14],"empow":[0,16],"empti":[2,7,8,17],"emul":[4,15],"enabl":[1,2,4,6,7,10,11,12,14,15,16,17],"enable_ratchet":11,"enable_remote_manag":15,"enable_transport":[8,14,15],"encapsul":[8,16],"enclos":5,"enclosur":0,"encod":[0,2,5,11,12,15,17],"encount":[0,4,10],"encourag":[0,1,4,17],"encrypt":[0,1,2,4,5,7,8,10,11,12,14,15,16],"encrypted_mdu":11,"encumbr":0,"end":[0,2,5,8,10,11,12,14,16],"endeavor":[0,1],"endless":[0,8,17],"endors":0,"endow":1,"endpoint":[2,10,11,12,14,17],"energi":[0,4,17],"enforc":[0,8,11,14,15],"enforce_ratchet":11,"engag":[0,1,17],"engin":[1,4,12,13,17],"enginest":0,"enhanc":14,"enjoy":1,"enorm":0,"enough":[0,1,4,6,8,12,14],"ensur":[0,1,2,4,5,8,10,11,12,14,15,16,17],"ensurepath":4,"entail":0,"enter":[1,2,15],"enterpris":0,"entertain":0,"enthusiast":0,"entir":[0,1,2,4,5,8,10,11,12,14,15,16,17],"entireti":0,"entiti":[1,10,14,15,17],"entitl":[0,1],"entri":[1,2,4,14,15,17],"entropi":17,"entrypoint":[7,8,15],"enumer":2,"envelop":[5,11,17],"environ":[0,1,4,5,7,8,10,13,14,15],"environment":14,"environmentlogg":14,"eof":8,"ephemer":[0,1,10,11,14,16],"epub":7,"equal":[0,1,10,11,14,17],"equat":0,"equip":[8,10,14],"equival":[0,5,8,17],"era":17,"eras":0,"eridanu":12,"erod":17,"eros":0,"erron":13,"error":[0,2,4,5,8,13,15,17],"esc":2,"esc_mask":2,"escal":0,"escap":[0,2,15],"esoter":1,"esp32":[0,6],"especi":[0,4,5,6,8,15],"essenc":0,"essenti":[0,1,4,5,8,12,14,15,17],"establish":[0,1,2,4,8,10,11,12,15,16,17],"established_callback":11,"establishment_timeout_per_hop":11,"estim":[0,11],"et":0,"etc":[0,5,15],"eth0":8,"eth1":8,"ether":17,"ethereum":13,"ethernet":[4,7,8,10,12,14,16,17],"ethic":[0,7],"etho":0,"evalu":[1,7],"evapor":17,"even":[0,1,2,4,5,8,10,11,12,14,15,16,17],"event":[0,8,9,17],"eventu":11,"ever":[0,14],"everi":[0,1,2,4,5,8,10,11,14,15,17],"everydai":4,"everyon":[0,1,4,5,12,13,14,17],"everyth":[0,1,2,5,10,12,13,14,17],"everywher":0,"evict":17,"evid":0,"evidentiari":0,"evolut":0,"evolv":[0,1,4,10,14],"exact":[0,5,6,8,14],"exactli":[0,5,11,14,17],"examin":0,"exampl":[0,1,4,6,7,10,11,12,14,15,16],"example_util":2,"exampleannouncehandl":2,"exampleconfig":[4,15],"exampleinterfac":2,"exce":[0,2,8,11],"excel":[0,12],"except":[0,2,8,11],"excerpt":0,"excess":[8,15],"exchang":[1,10,11,14,16],"exclud":[0,5,11,14],"exclus":[0,1,5],"execstart":15,"execstartpr":15,"execut":[0,1,2,4,5,8,11,15],"exemplifi":0,"exercis":[0,1],"exhaust":[0,6,12,14,15],"exist":[1,2,4,5,6,7,8,10,12,14,15,16],"exit":[1,2,5,8,11,15],"expand":[5,7,10,12,14,16],"expand_nam":11,"expans":[1,5,17],"expect":[0,2,5,8,11,13,14,15],"expens":[0,6,8],"experi":[0,10,12,14,15,17],"experienc":2,"experiment":[0,15],"expert":0,"expertis":0,"expir":[8,11],"expiri":[8,11],"explain":[0,6,11],"explan":[0,14,15],"explicit":[0,11],"explicitli":[0,8,10,14,15],"exploit":[0,1],"explor":[2,14,16,17],"explos":0,"export":[4,15],"expos":[0,8,11,15],"exposur":[0,8],"express":[1,5,7,9],"extend":[0,1,2,11],"extens":[0,5,8,15,16],"extent":0,"extern":[0,1,2,4,5,8,11,15,16,17],"extra":[0,4,8,15],"extract":[1,5,15,17],"extract_id":5,"extrem":[0,4,12,14,15,16,17],"ey":0,"f":[0,2,4,5,15],"f2d31b2e080e5d4e358d32822ee4a3b7":5,"f4":8,"f53a1c4278e0726bb73fcc623d6ce763":15,"fabric":[0,7,10],"facad":0,"face":[0,8],"facebook":1,"facil":0,"facilit":[12,14],"fact":[0,1,4,8,16],"factor":[0,8,11,15],"factual":0,"fade":17,"fail":[0,1,2,4,5,8,11,17],"failed_callback":[2,11],"failur":[0,1,4,5,8,11,17],"fair":7,"faith":0,"fake":[0,15],"fall":0,"fallaci":7,"fallback":[5,17],"fallen":17,"fals":[2,7,8,10,11],"falsehood":0,"falsiti":0,"famili":[0,4],"familiar":[0,1,12],"fantasi":[0,17],"far":[0,1,4,10,14],"farcic":0,"fart":0,"fashion":13,"fast":[0,7,8,10,11,12,14],"fast_flapping_block_tim":8,"fast_flapping_grac":8,"fast_flapping_threshold":8,"faster":[0,4,8,14,17],"fastest":[8,14],"fat":17,"favor":4,"favour":0,"fe80":4,"featur":[0,4,5,7,8,10,12,14,15,16],"feb":0,"fed":0,"feder":[0,12,14,15,17],"fedora":4,"fee":0,"feed":[0,1,4,11,17],"feedback":[0,1,2,7],"feel":[12,17],"feist":0,"ferment":7,"fernet":14,"fetch":[1,5,8,15],"few":[0,1,4,6,8,10,12,14,15,16,17],"fewer":11,"ff":15,"ffcffb4e255e156e77f79b82c13086a6":5,"fi":[5,13],"fiber":[6,17],"fibr":16,"fiction":0,"fictiti":0,"fidel":0,"field":[0,5,14,17],"fifth":0,"fight":0,"figur":8,"file":[0,1,2,4,5,6,8,9,10,11,12,14,15,16],"file_resourc":2,"file_s":2,"filelist":2,"filelist_data":2,"filelist_receiv":2,"filelist_timeout_job":2,"filenam":2,"filesync":7,"filetransf":[7,11],"fill":0,"filter":[1,2,10,14,15],"final":[0,2,5,11,14,17],"find":[0,1,5,7,8,12,14,15,17],"find_spec":2,"fine":[0,1,5,8,15],"fingerprint":17,"finish":[0,7],"finit":17,"fire":17,"firewal":[0,4,8,10,17],"firm":0,"firmli":0,"firmwar":[0,4,6,14,15],"firmware_hash":15,"first":[0,1,2,4,5,8,10,11,14,15,17],"fit":[1,2,9,17],"five":[2,17],"fix":[0,5,7,14,17],"fixed_mtu":8,"flag":[0,2,4,5,11,14,15],"flap":8,"flash":[0,15],"flasher":[0,4,7],"flat":[0,17],"flaw":[0,17],"fleet":14,"flesh":17,"flexibl":[4,5,6,8,10,12,15,16],"flexibli":5,"fli":14,"flicker":17,"flight":11,"flip":17,"float":[2,8,11],"flood":[0,8,15],"floor":0,"flourish":0,"flow":[0,1,2,4,7,8,10,14],"flow_control":8,"fluenci":7,"fluent":0,"fluentli":0,"fluid":17,"fluiditi":17,"fluidli":[0,17],"flush":2,"focu":[1,15],"focus":[0,12,14],"folder":[1,2,5],"folklor":0,"follow":[0,1,2,4,5,6,8,9,11,13,14,15,16,17],"font":5,"footnot":0,"footprint":0,"footsoldi":0,"forbid":[0,17],"forbidden":0,"forc":[0,1,2,15,17],"forcibli":[11,15],"foreground":4,"forens":0,"forese":0,"forev":[0,17],"forg":[0,17],"forgeri":0,"forget":[0,10,15],"forgiv":0,"forgotten":[0,1],"fork":[0,1,7],"forker":5,"form":[0,4,7,8,10,11,14,15,17],"formal":0,"format":[0,1,2,7,8,12,15,16],"formula":0,"forth":2,"fortifi":1,"fortiori":0,"fortun":17,"forum":0,"forward":[0,1,5,7,8,10,11,12,14,15,16],"forward_ip":8,"forward_port":8,"found":[0,2,4,5,8,11,14,15,17],"foundat":[1,7,10,13,14,16,17],"founder":0,"four":[0,8],"fourth":0,"fraction":0,"fragil":[1,7,17],"frame":[0,2,8],"framework":[0,12],"fraud":0,"fraudul":0,"free":[4,7,9,10,12,13,16,17],"freedom":[7,14,17],"freedv":6,"freeli":[0,14],"freq":15,"frequenc":[0,4,6,8,14,15],"frequent":[0,8,10],"fresh":0,"frictionless":0,"friend":[4,17],"friendship":0,"from":[1,2,4,5,6,7,8,9,10,11,12,13,14,15,16],"from_byt":11,"from_fil":11,"from_identity_hash":11,"fromhex":2,"front":[0,5,14],"fruit":2,"ftdi_ft230x_basic_uart_43891ckm":15,"fudg":0,"fuel":[0,17],"full":[0,1,2,4,5,8,10,11,12,14,15,16],"full_hash":11,"full_nam":[11,15],"fulli":[0,2,4,5,6,8,12,14,15,16],"fun":0,"funcion":11,"function":[0,1,2,4,5,6,7,8,9,10,11,12,13,15,16,17],"fund":0,"fundament":[0,1,6,10,14,15,17],"funnel":0,"furnish":9,"further":[0,1,4,7,8,15,17],"futur":[0,1,5,7,10,15,17],"fuzz":0,"fw":15,"g":[2,5,14,15],"ga":2,"gain":[1,6,11,14,17],"galact":14,"game":0,"gap":[0,4],"gaslit":17,"gatekeep":[0,1,14,17],"gatewai":[2,4,8,10,14,15,17],"gbp":[0,15],"gcc":0,"gear":17,"gemini":0,"gen_tim":5,"gener":[1,2,4,5,6,7,8,10,11,14,15,16,17],"generalis":16,"genuin":[0,15],"geograph":[1,4,8],"geoid":8,"get":[0,1,2,5,6,7,8,10,11,12,15,17],"get_ag":11,"get_channel":[2,11],"get_config_obj":2,"get_data_s":11,"get_establishment_r":11,"get_expected_r":11,"get_external_ip":8,"get_first_hop_timeout":11,"get_hash":11,"get_inst":11,"get_lowest_interface_bitr":11,"get_mdu":11,"get_medium_path_timeout":11,"get_mod":11,"get_mtu":11,"get_packet_rssi":2,"get_packet_snr":2,"get_part":11,"get_private_kei":11,"get_progress":[2,11],"get_public_kei":11,"get_q":11,"get_random_hash":[2,11],"get_remote_ident":[2,11],"get_request_id":11,"get_respons":11,"get_response_tim":11,"get_rssi":11,"get_rtt":[2,11],"get_seg":11,"get_snr":11,"get_statu":11,"get_transfer_s":11,"geti2p":8,"ghost":17,"ghostscript":0,"ghz":14,"gi":2,"giant":17,"gift":[0,17],"gigabit":[10,17],"gigabyt":16,"gile":0,"git":[1,7,15],"githook":0,"github":[0,1,2,4,5],"gitlab":1,"give":[4,8,14,15,17],"given":[0,8,10,11,14,15,17],"glanc":0,"global":[0,2,5,7,8,10,11,14,15,16],"globe":17,"glue":[0,6],"gmail":1,"gnu":0,"go":[0,2,8,10,12,14,17],"goal":[0,4,7,8,10,16],"goe":[0,17],"goldsmith":0,"gone":0,"good":[0,1,4,5,6,10,14,15],"goodwil":17,"googl":0,"got":[0,2,17],"got_respons":2,"govern":[0,14,17],"government":1,"gp":8,"gpg":5,"gpio":12,"gpl":0,"grab":0,"grace":11,"gracefulli":[8,10],"grade":7,"graham":0,"grain":[1,5,15],"grammar":1,"grant":[1,5,7,9,15,17],"granular":5,"grape":2,"graph":1,"gratefulli":13,"graviti":[8,17],"great":[0,4,5,12,14,15,17],"greater":[0,5,11,14,15,16],"greatli":[4,8],"green":17,"grep":5,"grew":0,"grid":[12,17],"grift":0,"gross":17,"ground":[0,1,17],"groundswel":0,"group":[0,1,7,8,11,12,14,15],"group_id":8,"group_nam":5,"group_root":5,"groupinstal":4,"grow":[0,1,4,17],"grown":17,"growth":[0,1,4],"guarante":[0,5,10,13,14],"guard":17,"guess":[0,8],"gui":12,"guid":[4,6,7,12,14],"guidanc":0,"guidelin":[0,4],"guilt":12,"gun":17,"gw":8,"gz":5,"h":[0,5,15],"ha":[1,2,5,6,7,8,10,11,12,13,14,15,16,17],"habit":[0,17],"habitat":[0,17],"hack":16,"had":[0,1,14],"half":[0,14,16],"hallucin":0,"halo":0,"hammer":17,"hancom":0,"hand":[0,2,17],"handheld":14,"handl":[0,1,2,4,5,6,8,10,11,12,14,15,16],"handler":[2,11,15,17],"handshak":17,"hang":0,"happen":[2,4,5,7,8,11,14,17],"happili":0,"har":0,"hard":[0,4,6,8,17],"hardcod":17,"hardlin":10,"hardwar":[0,1,2,4,7,8,11,12,14,15,16,17],"harm":[0,7,9],"harper":0,"harvest":[0,1],"has_path":[2,11],"hasattr":2,"hash":[1,2,5,10,11,14,15,17],"hash1":14,"hash2":14,"hash_from_name_and_ident":11,"hashlib":14,"hashmap":2,"hasn":0,"hastili":0,"hater":0,"haunt":0,"have":[0,1,2,4,5,6,8,10,11,12,13,14,15,16,17],"hazard":[0,11],"hdlc":2,"he":[0,1],"head":5,"headcount":7,"header":[0,2,5,8,11,14],"header_1":14,"header_2":14,"headlin":0,"health":7,"healthi":0,"hear":[14,17],"heard":[0,1,11,12,14,15],"heart":17,"heavi":[0,17],"heavili":0,"height":8,"heir":0,"held":[0,8,15],"helium":2,"hellman":[10,14],"hello":5,"hello_world":5,"help":[0,2,4,5,10,12,13,14,15,17],"helper":[2,5,15],"here":[0,1,2,4,8,14,15,17],"herebi":[0,9],"herein":0,"heterogen":[4,7,16],"hex":[2,15],"hexadecim":[2,5,14,15],"hexbyt":15,"hf":[12,17],"hi":0,"hidden":[0,15],"hide":[0,4,17],"hierarch":[16,17],"hierarchi":[7,17],"high":[0,6,8,10,14,15,16,17],"higher":[0,1,8,10,16],"highest":11,"highli":[0,5,8,13,14,15],"highlight":7,"hijack":[0,17],"hint":[2,5],"hire":0,"histor":1,"histori":[1,5,7,12],"hit":[0,2],"hkdf":14,"hmac":[14,16],"hobbi":0,"hobbyist":0,"hoc":[16,17],"hold":[0,8,11,14,17],"holder":[0,9,10],"hole":17,"holi":0,"hollow":[0,17],"home":[1,4,5,10,12,15,17],"homebrew":8,"honest":0,"honesti":0,"honestli":0,"honour":0,"hook":[0,1,5],"hop":[8,10,11,14,15,16,17],"hope":0,"hopefulli":10,"hops_to":11,"hospit":0,"host":[0,1,2,5,7,8,10,12,14,15],"hostil":[0,7],"hostnam":[8,17],"hotspot":17,"hour":[0,2,5,8,15,17],"hous":[4,17],"how":[0,1,2,4,5,6,8,10,12,14,15,16,17],"howev":[0,4,5,8,10,14],"http":[1,2,5,12,13,17],"hub":[0,8,12,15],"hum":17,"human":[0,1,2,7,8,9,10,11,13,14],"humanli":0,"hundr":[0,1,10,12,17],"hungri":6,"hw_mtu":2,"hwrev":15,"hypothesi":0,"hypothet":0,"hysteria":0,"hz":[8,12,15],"i":[1,2,4,5,6,7,8,9,10,11,12,13,14,15],"i2p":[4,7,10,12,16],"i2p_tunnel":8,"i2pd":[4,8],"i2pinterfac":[4,8],"i7":0,"ia":15,"ibm":0,"ic":6,"ic_burst_freq":8,"ic_burst_freq_new":8,"ic_burst_hold":8,"ic_burst_penalti":8,"ic_held_release_interv":8,"ic_max_held_announc":8,"ic_new_tim":8,"ic_pr_burst_freq":8,"ic_pr_burst_freq_new":8,"icmp":12,"icon":[5,17],"id":[0,5,8,11,14,15],"id_callsign":8,"id_interv":8,"id_regex":5,"idea":[1,4,5,7,14,15,17],"ideal":[12,15,16],"ident":[0,1,2,4,7,8,10,11,12,15,16],"identif":[7,8,16],"identifi":[0,2,5,8,10,11,14,15,16],"identifyexampl":2,"identity_data":15,"identity_hash":11,"ideolog":0,"ideologi":0,"ie":15,"if00":15,"ifac":[2,4,8,10,14,15],"ifac_s":8,"ifconf":2,"ifconfig":15,"ignor":[0,5,8,10,11,13,14,15],"ignored_devic":8,"ii":7,"iii":7,"illegitim":0,"illus":[0,7],"illustr":[0,2,8,14],"imag":[0,17],"imagin":[0,1,10,17],"immedi":[0,1,5,8,15,17],"immens":[0,17],"immort":17,"immun":1,"immut":[1,17],"impact":[8,10,11,14],"impati":17,"imperson":10,"implement":[1,2,5,7,8,10,11,12,14,15,17],"impli":9,"implic":[0,7,8,10],"implicit":[0,10,11,14],"implicitli":15,"import":[0,1,2,4,6,8,10,11,14,15],"importantli":[0,1,4,17],"importlib":2,"impos":0,"imposs":[0,14,17],"impostor":0,"impract":15,"impress":0,"improv":[0,4,7,8,12,13,17],"in_fram":2,"in_wait":2,"inabl":0,"inaccess":0,"inactive_for":11,"inadvert":15,"inbound":[2,8,11],"inbox":10,"inc":0,"incant":0,"incent":1,"incivil":0,"includ":[0,1,2,5,6,7,8,9,10,11,12,14,16],"inclus":10,"incoher":0,"incom":[2,8,11,15],"incommensur":0,"incompat":[1,11,14],"incompet":1,"incomplet":10,"inconveni":1,"increas":[5,8,11,15],"incredibli":[0,1,17],"increment":1,"incur":[1,8],"indefinit":[1,15],"independ":[0,1,5,7,11,14],"index":[2,4,7],"indic":[2,5,11],"indiffer":17,"indirectli":[0,9,14],"indistinguish":0,"individu":[1,4,5,7,8,11,13,14,15,16,17],"induc":0,"industri":[0,1],"inertia":0,"inevit":[4,14],"infer":[0,14],"infinit":17,"infinitum":0,"influenc":1,"influx":[8,12],"influxdb":12,"info":[5,11,14,15,17],"inform":[0,1,2,4,5,7,8,10,11,12,13,14,15,17],"infrastructur":[5,6,7,8,10,12,14,15],"infring":0,"ingest":[0,17],"ingo":11,"ingress":[2,7],"ingress_control":8,"inhabit":17,"inher":[1,10],"inherit":[0,5],"init":4,"initi":[0,2,5,8,10,11,14,15,16],"initialis":[2,5,11,15],"inner":0,"input":[0,2,15],"inquiri":0,"insert":14,"insid":[0,5,14,17],"insidi":[0,1],"insight":17,"insist":0,"insofar":0,"inspect":[0,4,5,8,10,14,15],"inspir":[12,17],"instal":[0,1,2,5,7,8,14,15,16],"instanc":[0,1,2,7,8,11,12,14,15,17],"instance_control_port":15,"instance_nam":15,"instant":[0,17],"instanti":11,"instantli":15,"instead":[0,1,2,4,5,8,11,14,15,17],"institut":[1,7,17],"institution":0,"instruct":[0,4,5,17],"instrument":0,"insuffici":0,"int":[2,11],"intact":0,"integ":[2,11],"integr":[0,1,4,5,12,14,15,17],"intellig":[0,1,9,17],"intend":[0,4,8,10,14,15],"intens":15,"intent":[7,10,17],"intention":[0,12,14],"inter":[4,11,14],"inter_byte_timeout":2,"interact":[0,1,2,4,7,10,11,12,14,15,17],"intercept":10,"interchang":[5,8],"interconnect":[4,8,10,14],"interest":[0,12,14,17],"interestingli":0,"interfac":[0,1,5,6,7,10,11],"interface_class":2,"interface_discovery_sourc":[11,15],"interface_en":15,"interfer":[10,15],"interlock":0,"intermedi":[10,17],"intermediari":[7,8,14],"intermesh":0,"intermitt":[1,8,10,17],"intern":[0,1,2,5,8,11,14,15,17],"internal_1":8,"internet":[0,1,7,8,10,12,14,15,16,17],"internetwork":4,"interop":0,"interoper":[6,10,12,14,16],"interpret":[0,5],"interregnum":7,"interrfac":0,"interrupt":[5,8],"interv":[5,8,11,15],"intervent":15,"intiat":2,"intim":17,"intox":0,"intric":0,"introduc":[1,5,14,15,17],"introduct":7,"introductori":7,"intuit":[10,14,16],"invalid":[2,5,8,11],"invari":17,"invent":0,"inventori":0,"invers":[0,14],"invert":[0,17],"invest":[0,1,10],"investig":[0,5],"invis":[4,8],"invit":[0,8],"invok":[0,5],"involv":[0,1,5,10,13],"io":6,"iodin":12,"ioerror":2,"iot":6,"ip":[0,4,6,7,8,10,14,15,16],"ipv4":8,"ipv6":[4,8,15],"irc":12,"ironi":0,"irrelev":[1,13],"irrespons":17,"is_compress":11,"is_connected_to_shared_inst":2,"is_open":2,"is_path_respons":11,"is_ready_to_send":[2,11],"isdir":2,"isfil":2,"isinst":2,"ism":[6,14],"isn":[0,17],"isol":[0,4,8,15],"isp":[8,10,17],"issu":[0,1,5,7,8,10],"issuer":0,"iter":0,"its":[0,1,5,6,8,9,10,11,12,14,15,17],"itself":[0,1,5,7,10,12,14,15,17],"iv":[7,14,16],"j":[7,15],"jacobsen":0,"jail":15,"jame":0,"jan":[0,5],"javascript":12,"jihad":0,"job":[0,1,2],"join":[2,4,10,12,14],"journal":0,"journei":10,"jsc":0,"json":[15,17],"judg":0,"judgment":[0,1],"judici":0,"juli":0,"jurisdict":0,"just":[0,1,2,4,5,6,8,10,12,14,15,16,17],"justif":0,"justifi":0,"k":[2,15],"katzer":0,"kb":15,"kbp":15,"keep":[0,2,4,5,10,11,14,15,16,17],"keepal":[11,14],"keepalive_timeout_factor":11,"kei":[0,1,2,5,7,8,10,11,15,16,17],"kenakafrosti":0,"kept":[0,8,10,11,14],"kernel":[1,8,15,16],"keyboard":0,"keyboardinterrupt":2,"keyerror":11,"keypad":12,"keypair":[10,14],"keyr":17,"keyserv":5,"keyset":[14,15,16],"keysiz":11,"keystor":10,"keyword":5,"khz":8,"ki":2,"kib":0,"kill":[11,14,17],"kilobit":12,"kilomet":1,"kind":[0,1,6,8,9,10,12,14,17],"kindergarten":0,"kiss":[6,7,15,16],"kiss_fram":8,"kissinterfac":[8,15],"knew":0,"knife":0,"knock":17,"know":[0,1,2,4,5,6,8,10,11,14,15,17],"knowledg":[0,10,14],"known":[0,2,8,11,14,15,16,17],"ko":13,"krypton":2,"l":[5,8,15],"la":15,"label":[0,1],"labor":[0,17],"lack":[0,1,14],"laid":14,"lake":1,"lament":0,"lan":8,"landlord":17,"landmark":0,"landscap":0,"languag":[0,1,5,9,12],"lantern":17,"laptop":[0,10,17],"larg":[0,2,6,8,10,11,14,15,16,17],"larger":[10,14,15],"laser":8,"last":[0,2,5,8,11,15,17],"last_read_m":2,"last_unit":2,"lat":8,"late":0,"latenc":[4,10,14,16,17],"later":[0,2,4,5,8,12,15],"latest":[1,2,4,5,8,11,12,15],"latest_buff":2,"latest_client_link":2,"latitud":8,"latter":0,"laucnh":4,"launch":[0,12,15],"launder":7,"law":[0,17],"layer":[1,6,7,8,10,11,12,14,15,16,17],"layout":0,"lc":0,"lcd":12,"lead":[0,4,14,17],"leadership":0,"leak":[0,4],"learn":[0,2,4,9,10,13,14,17],"leas":[0,17],"leash":17,"least":[0,4,5,6,8,10,14,15,16],"leav":[0,1,10,12,14,17],"ledger":[14,17],"leech":1,"left":[1,8,11,14,15],"legaci":[0,10,17],"legal":[1,7,8,17],"legisl":[0,8],"legitim":[0,4,10,15],"legitimaci":0,"len":[2,17],"lend":0,"length":[0,2,5,8,11,14],"less":[0,2,4,6,8,11,14,16,17],"let":[0,1,2,4,5,8,10,12,14,15,17],"letter":0,"level":[0,1,5,6,8,10,12,14,15],"lever":17,"leverag":0,"li":[1,17],"liabil":[0,9],"liabl":9,"lib":0,"liber":[6,7],"liberapai":13,"libffi":4,"librari":[1,4,12,17],"librn":12,"licens":[7,14,16,17],"license":0,"licensor":0,"lie":17,"life":[0,1,17],"lifelin":17,"lifespan":1,"lift":[11,15,17],"light":[1,5,15,17],"lightli":0,"lightweight":16,"like":[1,2,4,5,6,7,8,10,11,12,14,15,16,17],"likewis":5,"limit":[0,2,4,5,6,7,9,10,12,14],"line":[1,2,4,7,8,12,14,15,16,17],"linger":15,"link":[0,1,4,5,6,7,8,10,11,12,15,16,17],"link_clos":2,"link_establish":2,"link_id":[2,11],"link_mtu_discoveri":11,"linkexampl":2,"linux":[0,1,4,5,6,8,12,14],"liquid":17,"list":[0,1,2,4,5,6,7,8,11,12,14,16,17],"list_deliv":2,"list_fil":2,"list_filt":15,"list_packet":2,"list_receipt":2,"list_timeout":2,"listdir":2,"listen":[1,2,4,5,7,12,14,15,17],"listen_ip":8,"listen_on":[4,8],"listen_port":8,"liter":[0,15],"literari":0,"literatur":0,"lithograph":0,"litig":0,"litter":17,"littl":[0,6,12,14],"live":[0,1,4,11,12,17],"lki":14,"lkr":14,"ll":[0,2,16,17],"llama":0,"llc":0,"llm":[0,12],"ln":15,"load":[0,2,4,5,6,8,11,15,16,17],"load_private_kei":11,"load_public_kei":11,"local":[0,1,2,4,5,7,8,10,11,12,14,16,17],"locat":[0,4,7,8,10,12,14,15,17],"location_cmd":8,"lock":[0,17],"log":[0,1,2,4,5,8,15,17],"log_crit":2,"log_error":2,"log_info":2,"log_verbos":2,"logdest":11,"logfil":15,"logic":[0,14,17],"login":15,"loginctl":15,"loglevel":[2,11,15],"lon":8,"long":[0,2,4,5,6,7,8,10,11,14,15,17],"longer":[0,2,4,8,14,15,17],"longest":8,"longitud":8,"look":[2,4,5,7,8,10,12,14,15,17],"loop":[0,2],"loopback":0,"loophol":0,"loos":0,"lora":[1,4,6,7,10,12,14,16,17],"lorawan":[6,14],"lord":0,"lose":[0,1],"loss":[1,8,10,12,14],"lost":17,"lot":[0,10,14,17],"loud":0,"loudest":[0,17],"low":[0,1,4,5,6,8,10,12,14,16,17],"lower":[2,4,8,15],"lowest":[1,11],"lowli":17,"ltu":6,"lunar":7,"luxuri":0,"lxmf":[0,5,7,8,10,11,15],"lxmfy":7,"lxst":7,"m":[2,4,5,14,15],"m4":0,"mac":[8,14],"machin":[1,4,7,9,14,15,17],"machineri":[0,12],"maco":[0,7,12],"mad":7,"made":[0,4,5,8,11,14,17],"madman":0,"magic":0,"magnitud":0,"mai":[0,1,4,5,8,10,11,12,14,15,17],"mail":0,"mailbox":12,"mailmap":5,"main":[0,2,5],"maintain":[0,1,4,5,10,14,15,16],"mainten":[0,4,10,14,17],"major":[0,5],"make":[0,1,2,4,5,6,8,10,12,14,15,16,17],"maker":0,"malici":[1,4,5,10,14,15],"malinform":13,"man":0,"manag":[0,1,4,7,10,11,12,14,16,17],"mani":[0,2,4,5,6,8,10,11,12,14,15,16,17],"manifest":[1,5],"manipul":[14,16,17],"manjaro":4,"manner":[0,5,10,12],"manual":[0,1,2,4,8,10,11,12,14,15,16,17],"manufactur":[0,6,8],"map":[8,12,14,15,17],"mar":0,"margin":0,"mark":[0,4,5,8,9,11,14,16,17],"markdown":5,"marker":0,"market":[0,1,17],"markqvist":[2,13],"markup":[5,12],"mask":1,"masquerad":0,"mass":[0,17],"massiv":[0,8],"mast":0,"master":[2,5,11,17],"match":[0,1,2,5,8,14,15,17],"materi":[0,12],"math":17,"mathemat":[0,17],"matter":[1,4,7,8,10,17],"matur":15,"max":15,"max_request_s":11,"max_response_s":11,"maximum":[2,8,11,14,15],"mayb":17,"mb":[0,5],"mbp":[0,15],"md":[0,5],"mdu":[2,11],"mdy":0,"me":[0,8,17],"mean":[1,4,5,6,7,8,10,11,14,15,17],"meaning":[0,4],"meaningfulli":0,"meaningless":[0,1],"meant":0,"meantim":11,"measur":[0,1,10,14,17],"mechan":[0,1,4,5,7,8,10,15,16],"media":[0,5,17],"mediat":[0,1],"mediev":17,"medium":[0,1,2,6,7,8,10,11,12,14,16],"meet":[0,1,17],"megaphon":17,"member":[0,4,14],"membership":0,"memori":[0,4,10,14],"men":1,"mental":17,"mention":[0,8,14],"menu":2,"menu_mod":2,"merchant":9,"merci":0,"mere":[0,1,17],"merg":[0,1,9,15],"merit":[0,7],"mesh":[0,4,8,10,14,15,16,17],"meshchat":0,"meshchatx":7,"messag":[0,2,4,5,7,10,11,14,15,17],"message_class":11,"messagebas":[2,7,11],"messagecallbacktyp":11,"messeng":[10,14],"met":[0,1,4,17],"meta":5,"metadata":[1,4,5,8,14,15,17],"metaphor":17,"metavar":2,"meter":8,"meth":2,"method":[2,4,7,8,11,14],"methodologi":[0,14,15],"metric":[1,12],"mevpekyafshak5wr":8,"mhz":[8,14],"mi":2,"mib":0,"microcontrol":[0,14],"micromanag":17,"micron":[5,7],"microsoft":0,"microsystem":0,"microwav":10,"mid":0,"middl":1,"middlemen":1,"midjournei":0,"midnight":0,"might":[0,1,4,5,8,10,14,15,17],"migrat":1,"mikrotik":6,"mileston":0,"millimet":6,"million":[0,17],"millisecond":[2,10,15,17],"mind":[0,1,10,17],"mindset":17,"mine":[0,17],"minefield":0,"miner":17,"minim":[0,1,6,7,8,14],"minimalsampl":2,"minimum":[0,2,4,8,11,14,15,17],"minimum_bitr":11,"miniscul":17,"minor":5,"mint":0,"minut":[0,2,4,5,8,14,17],"mirror":[0,1,7,10,12,15],"mirror_interv":5,"mischaracteris":0,"misconcept":0,"misconfigur":4,"mislabel":0,"mislead":[0,4,17],"mismatch":0,"misrepres":0,"miss":[0,2,4,5],"missil":17,"mistak":[0,4],"mistaken":0,"misunderstand":13,"mit":0,"mitig":10,"mix":[7,8,10,15],"mixtur":16,"mobil":[8,10,12,14],"mode":[0,1,2,4,5,6,7,10,11,12,14,15,16,17],"model":[0,1,9,10,15,17],"modem":[7,8,10,11,12,14,16,17],"modem73":7,"modem73interfac":12,"moder":[0,8],"modern":[0,4,6,12,17],"modif":[0,1,5],"modifi":[0,1,5,8,9,10,14,15],"modul":[0,2,4,5,6,7,8,10,14,15,16],"modular":12,"moment":[0,14,17],"momentarili":8,"mon":5,"monei":0,"monero":13,"monet":1,"monitor":[4,8,12,14,15],"monolith":1,"monopol":1,"month":0,"monthli":0,"mood":0,"moon":2,"moral":[0,17],"more":[0,1,2,4,5,6,8,10,11,12,13,14,15,16,17],"moron":0,"moscow":[12,14],"most":[1,4,6,7,8,10,11,12,14,15,17],"mostli":[0,8,10,14],"motion":0,"motiv":[0,7],"mountain":[0,17],"move":[0,5,8,10,14,15,17],"movement":7,"msg":0,"msgpack":5,"msgtype":[2,11],"msvc":0,"mtu":[2,8,11,12,14,16],"mu":5,"much":[0,4,8,10,12,14,15,16,17],"muddi":0,"multi":[1,7,10,12,14,15,16],"multicast":8,"multicast_address_typ":8,"multilater":14,"multipl":[1,2,5,8,10,12,14,15],"multiplex":[2,15],"multipoint":14,"multitud":4,"mumbl":12,"music":[0,1,12],"must":[0,1,2,4,5,8,10,11,14,15,17],"mutat":0,"mutual":17,"mw":8,"my":[0,5,8,14,17],"my_fil":15,"my_ident":15,"my_network":[14,15],"my_network_ident":8,"my_nod":5,"myapp":5,"mycal":8,"myfork":5,"myfriend":17,"mymirror":5,"myrepo":5,"myriad":14,"mysteri":17,"n":[0,2,5,14,15],"name":[0,2,4,5,7,8,10,11],"name_of_other_branch":5,"namespac":2,"nano":5,"narg":2,"narr":0,"narrat":0,"narrow":0,"nat":[4,8],"nation":[0,1],"nativ":[0,2,10,12],"natur":[0,1,8],"navig":[0,1,5],"ncurs":12,"nearbi":[8,10],"nearest":8,"nearli":0,"nears":14,"neat":10,"neccessari":8,"necesarri":8,"necess":[0,1],"necessari":[0,1,5,6,8,10,11,14,15],"necessarili":14,"need":[0,1,2,4,5,6,7,8,10,11,12,13,14,15,16,17],"needless":8,"neg":[4,8],"neglig":[14,17],"negoti":[1,17],"neighbor":17,"neighbour":0,"neighbourhood":0,"neither":[0,11,14],"neon":2,"neopixel":15,"nerd":5,"net":8,"netcat":8,"network":[1,2,6,8,11,15,16,17],"network_ident":[8,14,15],"network_nam":[4,8],"neutral":[0,10,17],"never":[0,1,8,10,11,14,17],"new":[1,2,4,5,7,10,11,14,15,17],"new_id":15,"new_ident":15,"newcom":0,"newer":[11,14],"newest":14,"newli":[8,11,14],"newlin":[8,15],"next":[0,1,4,5,8,11,14,17],"next_hop":11,"next_hop_interfac":11,"nice":17,"nicknam":14,"nilli":0,"nine":0,"nixo":0,"no1cll":8,"no_data_for":11,"no_id":5,"no_inbound_for":11,"no_outbound_for":11,"no_std":0,"noauth":15,"nobl":2,"noble_ga":2,"noble_gas":2,"nobodi":[0,5],"nocheck":15,"node":[0,1,4,7,8,15,16],"node_nam":5,"noid":15,"nois":[0,1,8,11,13,17],"noisi":17,"nomad":[1,7],"nomadnet":[0,5,12],"non":[0,4,5,8,11,12,14,17],"none":[0,2,4,5,8,11,14,15],"nonetheless":0,"nonexclus":0,"noninfring":9,"nonsens":0,"nonstandard":0,"nor":[0,4,17],"normal":[0,1,2,4,5,8,11,14,15],"nostalgia":1,"notabl":12,"notar":5,"notaris":0,"notat":[14,15],"note":[0,1,2,5,6,7,8,11,14,15],"noth":[0,5,6,10,16,17],"notic":[0,5,8,9,14,15],"notif":[1,2,11],"novel":0,"now":[0,2,4,5,14,15,17],"nowher":0,"np":15,"nrf":0,"nrf52":6,"nrf52840":0,"nt":2,"nuanc":0,"null":5,"num":2,"number":[0,2,4,5,8,10,11,12,14,15,17],"nurtur":1,"o":[0,2,4,5,8,14,15,16],"obj":5,"object":[0,2,5,11,17],"oblig":0,"obscur":[0,1,4],"observ":[0,1,10,17],"obsess":0,"obsolet":17,"obstacl":17,"obtain":[0,1,4,6,7,9,11,14],"obviou":0,"obvious":14,"oc":0,"occas":0,"occasion":0,"occupi":17,"occur":[0,2,8,15,16],"ocean":17,"ocur":11,"odd":2,"odin":12,"off":[0,4,8,10,12,14,15,16,17],"offer":[0,1,4,7,8,10,11,12,14,15,17],"offic":[0,10],"offici":0,"offlin":[0,1,2,4,7,10,12],"often":[0,1,4,8,10,14,15,17],"oganesson":2,"old":[0,1,2,4,6,12,13,14,17],"older":[0,15],"oldest":0,"omit":11,"on_interfac":11,"onc":[0,2,4,5,6,8,11,14,15,16,17],"one":[0,1,2,4,5,6,8,10,11,12,14,15,16,17],"ones":[0,4,8,10,15],"oneself":14,"ongo":12,"onli":[0,1,2,4,5,6,8,10,11,12,14,15,16,17],"onlin":[0,2,11,15,17],"onto":[0,4,14,17],"ontolog":1,"opaqu":[0,10],"open":[1,2,4,5,6,7,8,10,11,12,13,14,15,16],"open_port":2,"openli":0,"openmodem":[8,16],"openssl":[4,14],"openwrt":7,"oper":[0,1,4,5,6,8,10,11,12,14,15,16,17],"opinion":[1,13],"opkg":4,"opportun":4,"opportunist":10,"oppos":[0,5],"opposit":[0,2,8],"oppress":17,"opt":14,"optic":[6,16,17],"optim":[0,1,4,5,10,17],"option":[1,2,4,5,6,7,10,11,12,14,15,17],"oracl":0,"orbit":0,"ord":2,"order":[0,1,2,8,11,15],"ordinari":0,"organ":[0,1,4,5,10,14,15,17],"organis":[0,8],"organiz":1,"orient":[0,14],"origin":[0,2,5,7,10,14,17],"orthodoxi":0,"orthogon":1,"os":4,"osi":0,"other":[1,2,4,5,6,7,8,9,10,11,12,14,15,17],"otherwis":[0,2,5,8,9,11],"our":[0,2,8,14,17],"ourselv":10,"out":[0,2,6,8,9,11,12,14,15,17],"outag":1,"outbound":[8,11,14],"outcom":0,"outdat":0,"outgo":[2,8,11,14,15],"outlast":1,"outlin":[0,4,6,14],"outperform":0,"output":[1,5,7,8,15],"outrag":0,"outright":0,"outsid":[0,11,16,17],"outward":0,"over":[0,2,6,7,8,10,11,13,14,15,16,17],"overal":[7,14,15],"overcom":14,"overhead":[4,6,8,14,17],"overlai":4,"overlap":0,"overli":13,"overlord":17,"overrid":[2,5],"oversight":[0,14],"overview":[5,7,8],"overwhelm":[0,1,8,10,11],"overwrit":15,"ow":0,"own":[0,1,2,4,5,10,11,12,14,15,16,17],"owner":[0,2,17],"ownership":[0,1,17],"p":[2,5,15],"pace":1,"pack":[2,11],"packag":[0,1,2,4,5,8,12,14],"packb":2,"packed_s":2,"packet":[0,1,2,4,7,8,10,11,12,15,16,17],"packet_callback":2,"packet_deliv":2,"packet_hash":2,"packet_receipt":[2,11],"packet_timed_out":2,"packetreceipt":[2,7,11],"pad":[14,16],"page":[0,1,7,14,15,17],"page_cont":5,"pagin":5,"paid":1,"painstak":0,"painstakingli":0,"pair":[8,11,14,15],"pamac":4,"panic":[2,15,17],"panic_on_interface_error":[2,15],"panopticon":17,"paper":12,"par":[2,4],"paradigm":0,"paradox":17,"parallel":4,"paralysi":17,"param":2,"paramet":[2,6,7,11,14,15],"paranoia":17,"parasit":[0,17],"pariti":[0,2,8,15,16],"parity_even":2,"parity_non":2,"parity_odd":2,"pars":[2,5],"parse_arg":2,"parser":[0,2,5,7],"part":[0,1,2,4,5,8,10,11,12,14,15,17],"parti":[0,1,5],"partial":[0,5],"particip":[0,1,4,7,8,10,14,15,17],"participant_nod":0,"particular":[0,1,2,6,8,9,14,15],"particularli":[1,5,8,15],"partli":0,"partner":17,"partylin":7,"pass":[2,5,6,8,10,11,14,15,17],"passphras":[4,8,10,14],"passport":14,"past":[0,15],"patch":[1,5,17],"patent":0,"path":[0,1,2,4,5,6,7,10,11,12,14,15,17],"path_respons":11,"pathfinder_m":11,"patient":17,"pattern":[1,5,6,7,10,14],"paydai":0,"payload":[0,2,5,8,11,14,15],"pc":0,"pdf":7,"peac":17,"peach":2,"peak":[0,5],"peer":[0,1,2,4,5,8,11,12,14,15,17],"penalti":8,"pend":[2,14],"peopl":[0,1,4,12,14,17],"per":[0,1,5,8,10,11,12,14,15,16,17],"percent":[2,8],"percentag":11,"perfect":0,"perfectli":[1,4],"perform":[1,2,4,5,7,8,10,11,12,14,15,17],"perhap":[4,17],"period":[0,2,5,8,11,14,15],"peripher":12,"peripheri":0,"perlmutt":0,"perm":5,"perman":[4,8,15],"permiss":[0,1,7,8,9,15,17],"permissionless":[1,14,15],"permit":9,"perpetu":[0,17],"persecut":14,"persist":[1,7,8,15,17],"person":[0,7,8,9,10,13,14],"personag":1,"perspect":[0,1,8,10,11,14,16],"persuad":0,"pervers":0,"pet":2,"petit":17,"petti":0,"phantom":0,"phenomenon":0,"philosophi":[1,13,14,16,17],"phoenix":0,"phone":[0,4,7,10,17],"phonebook":12,"phonorecord":0,"photo":17,"photocopi":0,"phrase":0,"phy":15,"physic":[0,1,2,4,5,6,7,8,10,11,12,14,15,16],"pi":[1,2,7,10,14,15,16,17],"pick":[0,14],"pictur":0,"piec":[0,14],"pierian":0,"pillar":17,"pin":0,"ping":[15,17],"pip":[0,2,4,5,6,8,15],"pip3":4,"pipe":[7,12,15,16,17],"pipeinterfac":[6,8,12],"pipelin":0,"pipx":4,"piss":0,"pitch":0,"pitfal":14,"pkcs7":[14,16],"pkg":4,"place":[2,4,5,7,8,10,14,15,17],"plaform":6,"plain":[0,2,6,8,11,14,17],"plain_mdu":11,"plainli":0,"plaintext":[2,11,17],"plan":[0,10,14,17],"planet":[1,17],"planetari":[16,17],"platform":[0,2,5,6,7,12,14,15,17],"plausibl":0,"plausibli":0,"pleas":[2,4,8,11,15,17],"plenti":[10,14],"plethora":0,"plu":11,"plug":[15,17],"plugin":[12,17],"plural":0,"pmr":14,"pocket":0,"poetri":17,"point":[0,1,4,5,6,8,10,12,13,14,15,17],"pointer":4,"polici":[0,1,15,17],"polish":0,"polit":[0,17],"pomelo":2,"pope":0,"popul":[0,11],"popular":[0,16],"port":[0,2,4,6,7,8,10,14,16,17],"port0":15,"portabl":[1,7,8,10,14],"portion":[0,9],"pose":[0,4,14],"posit":[2,5,7,8,15],"posix":4,"possess":[0,8,14,17],"possibl":[1,4,5,6,7,8,10,11,12,14,15,16],"possibli":[0,4,14],"post":[0,2,7],"postfix":15,"postur":0,"potenti":[0,1,2,4,5,8,13,14,15,16,17],"pour":0,"power":[0,1,4,6,7,8,10,12,14,15,16],"powershel":4,"ppp":2,"pr":15,"practic":[0,1,5,10,14,16,17],"prais":0,"pre":[0,4,10,11,14],"preambl":[8,15],"prebuilt":0,"preced":[0,2,5],"preciou":10,"precis":[0,1],"precompil":4,"predatori":17,"predic":1,"predict":[7,14],"preexist":0,"prefer":[0,4,5,13,14],"prefer_ipv6":8,"prejudic":0,"premis":[0,10,17],"prepar":[0,2,14],"preposter":0,"prerequisit":[7,11],"prescrib":1,"presenc":[0,1,7,8,11],"present":[1,7,8,10,12,14,15,17],"preserv":[0,1,4,7,11],"preshar":14,"press":[0,2],"pressur":1,"prestig":0,"pretend":[0,12,14],"prettyhexrep":2,"prevent":[0,1,5,8,10,15,17],"preview":5,"previou":[0,2],"previous":[0,8,11,14],"price":17,"primari":[0,1,5,14,17],"primarili":[0,8,10,12],"primarlii":4,"prime":0,"primit":[0,4,5,7],"princip":0,"principl":[1,7,10,14,16],"print":[2,5,8,15],"print_filelist":2,"print_help":2,"print_menu":2,"prior":0,"priorit":[0,8,10,14,17],"prioriti":[0,8,14],"prioritis":[7,8,10,11],"privaci":[4,8,12,17],"privat":[1,4,5,8,10,11,12,13,14,15,16,17],"private_ret":4,"privileg":[1,15,17],"prn":7,"probabl":[0,2,4,5,10,14,15,16],"probe":15,"problem":[0,1,4,5,14,15,17],"problemat":5,"proc":15,"proce":0,"procedur":[0,4,5,11,14],"process":[0,1,2,4,5,6,8,10,11,14,15,17],"process_incom":2,"process_outgo":2,"proclaim":0,"proclam":0,"produc":[0,1],"product":[0,1,15,17],"profil":17,"profit":[0,17],"profound":[10,17],"profoundli":17,"program":[0,2,5,6,7,8,11,14,16],"program_setup":2,"programm":[0,14],"programmat":[1,14],"progress":[0,2,5,11,15,16],"progress_callback":11,"prohibitevli":0,"project":[1,5,7,12,13,17],"promis":[0,4],"promot":0,"prompt":[0,2,4],"prompter":0,"proof":[0,1,2,5,8,10,11,14,15,17],"proof_packet":2,"proof_requested_callback":11,"proof_strategi":11,"prop":0,"propag":[0,7,8,10,11,12,15,17],"proper":4,"properli":[0,4],"properti":[1,2,7,10,11],"proport":14,"proportion":0,"propos":[0,7],"prose":0,"prospect":1,"protect":[1,4,7,15,17],"protocol":[0,4,5,6,7,8,10,16],"prototyp":12,"proudli":0,"prove":[0,2,5,10,14,17],"prove_al":[2,11],"prove_app":11,"prove_non":11,"proven":[1,5,11,14],"provid":[0,1,2,4,5,6,7,8,9,10,11,12,14,15,16,17],"provis":[0,6,15],"prv_byte":11,"prx":15,"pseudo":15,"psycholog":[1,17],"ptt":12,"ptx":15,"pub_byt":11,"pub_to_fil":11,"public":[0,2,5,7,8,10,11,12,13,15,16],"public_inform":2,"publicli":[0,4,8,14,15],"publish":[0,1,4,5,7,8,9,11,14],"publish_blackhol":15,"publish_blackhole_en":11,"publish_ifac":8,"pull":[0,1,5],"puppet":17,"purchas":[4,14,16],"pure":[0,7,14],"purg":11,"purport":0,"purpos":[1,4,5,6,7,8,9,10,11,12,14,15,17],"purposefulli":[0,9],"pursu":1,"push":[1,5,12,17],"put":[0,1,2,6,8,15],"pwd":5,"py":[0,2,5,14,15],"py3":[4,5],"pyca":[4,14],"pyd":0,"pygment":5,"pyseri":[2,4],"python":[0,1,2,5,7,8,11,14,15,16,17],"python3":[2,4,6],"pyximport":0,"q":[2,5,15],"q8_k_xl":0,"qlen_in_announc":8,"qlen_in_data":8,"qlen_in_il":8,"qlen_in_pr":8,"qr":[10,12],"qua":0,"qualiti":[0,1,11,15,17],"quant":0,"quantiti":1,"quantum":0,"queri":[2,4,5,11,15,17],"question":[4,6,7,8],"queu":[11,15],"queue":[7,14,15],"quick":15,"quickli":[0,8,12,14,16],"quiet":[5,8,15,17],"quietest":0,"quill":0,"quinc":2,"quirk":4,"quit":[0,2,4],"quot":[0,5],"qvist":[9,16],"r":[0,2,5,8,14,15],"radic":17,"radio":[0,1,7,8,10,11,12,14,15,16,17],"radon":2,"rain":0,"rais":[0,1,2,11],"rak":6,"ram":[0,4,8],"ramp":0,"randint":2,"random":[0,1,2,11,13,14],"random_text_gener":2,"randomis":14,"randomli":[2,14],"rang":[0,1,2,4,5,6,8,10,14,15,16,17],"rapidli":[0,8],"rare":[4,8],"raspberri":[1,7,10,14,15,16],"rasperri":4,"ratchet":[0,11,14],"ratchet_count":11,"ratchet_expiri":11,"ratchet_id_receiv":11,"ratchet_interv":11,"ratchets":11,"ratchets_path":11,"rate":[0,2,4,7,11,12,15],"rather":[0,1,4,11,15,17],"ratio":[0,1,11],"rational":0,"raw":[0,2,5,6,11],"rawchannelread":[7,11],"rawchannelwrit":[7,11],"rawiobas":11,"rawmu":5,"rb":2,"re":[0,1,2,8,10,11,14,15,17],"reach":[0,1,4,7,8,10,11,15,17],"reachabl":[1,2,4,8,10,11,12,14,15],"reachable_on":8,"reaction":0,"reactiv":[0,1],"read":[0,1,2,4,5,8,10,11,12,14,15,16,17],"read_loop":2,"readabl":[0,1,2,8,11,14,15,17],"reader":[0,2,11],"readi":[2,4,6,8,11,16,17],"readili":16,"readm":[0,5],"readwrit":5,"ready_byt":[2,11],"ready_callback":11,"real":[0,1,4,6,8,10,12,15,16,17],"realist":0,"realiti":[1,4,17],"realiz":17,"realli":[0,8,11,15,17],"realm":17,"realtim":12,"reappear":8,"reason":[4,7,8,11,14,15],"reassembl":14,"reboot":17,"rebroadcast":10,"rebuilt":17,"rebutt":0,"recal":[0,2,5,11,15],"recall_app_data":11,"recap":14,"recast":0,"receipt":[2,10,11,14],"receiv":[0,2,4,5,8,10,11,13,14,15,17],"receive_path_respons":11,"receive_stream_id":11,"received_announc":[2,11],"recent":[0,11,14],"recept":11,"reception_rssi":2,"reception_snr":2,"reception_stat":2,"recip":4,"recipi":[1,5,14,17],"reciproc":0,"reclaim":17,"recogn":[0,14,17],"recognis":[0,15],"recognit":[1,7,17],"recombin":1,"recommend":[1,2,4,8,14],"recondit":15,"reconnect":[2,10,17],"reconnect_port":2,"reconstruct":14,"record":[0,1,4,5,14],"record_stat":5,"recov":1,"recoveri":8,"recreat":14,"recur":0,"recurr":0,"recurs":[0,8,11,14],"recursive_pr":8,"recycl":7,"red":0,"reddit":0,"redistribut":0,"reduc":[0,8,15],"redund":[4,10],"reestablish":1,"ref":5,"refactor":[0,5],"refer":[1,2,4,5,7,8,12,15,17],"referenc":0,"referenti":0,"refin":[0,13],"reflect":[0,1],"reflex":0,"refram":0,"refresh":15,"refus":[0,10],"refut":0,"reg":0,"regain":[1,4],"regard":[0,1,12,14],"regardless":[0,1,5,8],"regener":0,"region":8,"regist":[0,2,5,11,15],"register_announce_handl":[2,11],"register_message_typ":[2,11],"register_request_handl":[2,11],"registr":0,"registrar":17,"registri":[1,17],"regrett":0,"regul":8,"regular":15,"regularli":0,"regulatori":17,"regurgit":[0,17],"reid":0,"reimplement":0,"reintroduc":1,"reject":[0,5,17],"rel":[0,5,6,8,10,14],"relai":[0,4,7],"relat":[0,4,5],"relationship":[0,1,10,14,15,17],"releas":[0,1,4,7,8,14,15,17],"relev":[0,2,4,5,6,8,11,14,15,17],"reli":[0,4,5,8,10,13,14,15,17],"reliabl":[0,4,6,8,10,11,14,16,17],"relianc":[4,17],"relief":10,"reload":15,"rem":2,"remain":[0,1,5,8,10,11,12,14,17],"remaind":0,"rememb":[8,10,11,14],"remind":0,"remot":[2,7,11,14],"remote_ident":[2,5,11],"remote_identifi":2,"remote_management_allow":15,"remote_management_en":11,"remote_nod":5,"remote_p":2,"remotesensor":14,"remov":[0,1,5,11,15,17],"remove_message_handl":11,"remove_ready_callback":11,"ren":7,"renam":0,"render":[5,12,17],"rendezv":0,"rent":17,"rental":0,"reopen":5,"rep":0,"repeat":0,"repeatedli":[0,1,8],"replac":[0,1,2,4,10,11,12,14,15,17],"repli":[0,2,15],"replic":[1,6,14],"reply_data":2,"reply_messag":2,"reply_text":2,"repo":[5,15],"repo_nam":5,"report":[0,8,11,13,15],"repositori":[0,1,4,7,12,14,15,17],"repres":[0,1,10,14,17],"represent":[2,11,17],"reproduc":0,"reproduct":0,"republish":0,"repudi":5,"repurpos":4,"reput":[14,15],"request":[0,1,5,7,10,11,14,15,16,17],"request_destin":2,"request_fail":2,"request_id":[2,11],"request_packet":2,"request_path":[2,11],"request_receipt":[2,11],"request_receiv":2,"requested_at":[2,11],"requestexampl":2,"requestor":8,"requestreceipt":[7,11],"requir":[0,1,2,4,5,8,10,11,12,14,15,16,17],"require_shared_inst":11,"required_discovery_valu":[11,15],"rerout":17,"rescu":7,"research":1,"resend":11,"reserv":[0,2,10,11,17],"reset":5,"reshap":1,"resid":[8,12,17],"resili":[0,1,4,10,12,15,16,17],"resist":10,"resiz":15,"resolut":[0,4,5,8,14],"resolv":[5,7,8,10,14,15],"resort":0,"resourc":[0,2,4,7,8,10,11,13,15,17],"resource_callback":11,"resource_sending_conclud":2,"resource_strategi":11,"respawn":8,"respawn_delai":8,"respawn_interv":8,"respect":[0,1,5,8,10,16,17],"respond":[0,1,2,10,11,15],"respond_to_prob":15,"respons":[1,7,8,11,14,16,17],"response_callback":[2,11],"response_gener":[2,11],"rest":[0,10,16,17],"restart":[8,15],"restartsec":15,"restor":[0,4,7,8,17],"restrict":[5,7,8,9,10,15,17],"resubmit":5,"result":[0,1,2,4,8,14,15],"ret":[7,14],"retain":[0,1,5,8,11],"retained_ratchet":11,"retibb":7,"reticul":7,"reticulum":[1,2,8,10,11],"retipedia":7,"retransmiss":[10,14],"retransmit":[8,14],"retreat":0,"retri":[0,2,5,11,14],"retriev":[1,5,11,15],"return":[1,2,8,11,15,17],"reveal":[4,11,14,16],"revers":[0,15],"revert":0,"review":[0,1,14],"revis":[0,15],"revisit":0,"revok":[5,17],"revolut":17,"revolutionari":1,"rewrit":0,"rfe":15,"rhetor":0,"rich":12,"ridicul":[0,14],"right":[0,1,4,5,8,9,17],"rigid":17,"rigor":0,"rington":12,"rippl":17,"risc":7,"risk":[5,14],"riski":17,"rm":5,"rmap":4,"rn":[0,1,2,4,5,6,7,11,14,15,17],"rncp":7,"rngc":5,"rngit":[1,7,12],"rngit_config":5,"rnid":[5,7,14],"rnmon":7,"rnode":[4,7,12,14,15,16],"rnodeconf":[6,7,12],"rnodef3b9":8,"rnodeinterfac":[4,6,8,15],"rnodemultiinterfac":8,"rnpath":[4,7,8],"rnphone":12,"rnprobe":[4,7],"rns_bin_dir":15,"rns_config":5,"rns_remot":5,"rnsconfig":[5,15],"rnsd":[0,4,7],"rnsh":[7,12],"rnspure":[4,14],"rnstatu":[4,7,8,14],"rnstransport":[8,15],"rnx":7,"road":[7,17],"roadmap":17,"roam":[7,8,10],"robot":14,"robust":[4,8,17],"role":[7,10],"roll":8,"rom":15,"room":[7,12,17],"root":[0,5,14],"rotat":[8,11,14,15],"rou":0,"roughli":0,"round":[0,2,11,15],"roundtrip":0,"rout":[0,4,6,8,10,11,12,14,15,16,17],"router":[4,8,10,15,17],"row":0,"rpc":15,"rpc_kei":15,"rprogress":2,"rrc":7,"rrcd":12,"rsg":[1,5],"rsm":[1,5],"rssi":[2,11,15],"rtsct":2,"rtt":[2,11,14],"rttstring":2,"rubber":17,"rule":[0,1,4,5,7,8,10,15,17],"run":[0,1,2,4,5,6,8,10,11,12,14,15,16,17],"runtim":[2,14],"rural":0,"rust":[0,4],"rvp":5,"rw":5,"rx":[8,15],"rxb":2,"ryzen":0,"s3":0,"sa":12,"safe":[5,14,15,17],"safeguard":17,"safer":0,"safeti":[0,1],"sai":[0,1,17],"said":[0,5,14],"sake":[0,1],"sale":0,"same":[0,1,2,4,5,6,8,10,11,12,14,15,17],"sand":17,"saniti":0,"saroni":0,"satellit":10,"satisfi":[0,14],"satur":1,"saturdai":0,"save":[0,5,11,14,15],"save_error":2,"saved_filenam":2,"saw":[0,12],"scaffold":0,"scalabl":[15,16],"scale":[0,14,16,17],"scan":[4,8],"scandal":0,"scarc":17,"scarcest":0,"scarciti":7,"scatter":17,"scenario":[0,4,8,14],"schedul":[0,5,11],"scheme":[1,5,6,8,15],"scholarship":0,"school":[0,12],"scienc":0,"scope":[5,7,8],"scrape":[0,17],"scratch":[0,6,17],"scream":0,"screen":[0,2],"script":[1,4,5,6,8,15],"scrub":0,"scrubber":0,"scrutini":[0,14],"sd":1,"sdk":0,"se":5,"sea":8,"seal":0,"seamless":[8,12,14],"seamlessli":[8,10,12],"search":[7,11,12],"seat":0,"second":[0,2,8,10,11,12,14,15,16,17],"secreci":[8,11,12,14,16],"secret":[0,10,14],"section":[0,4,5,6,8,10,12,14,15],"secur":[0,1,4,5,7,10,12,14,15,16,17],"sed":5,"see":[0,2,4,5,8,10,11,14,15,16,17],"seek":[0,1,14,17],"seem":0,"seen":[0,8,14,17],"segment":[2,4,8,10,11,14,15,16],"seiz":0,"seizur":0,"selden":0,"select":[0,2,4,5,8,17],"self":[0,1,2,4,5,14,16,17],"sell":[0,9],"semant":0,"semi":[5,15],"semtech":6,"send":[0,2,5,8,10,11,14,15,17],"send_stream_id":11,"sender":[2,4,10,14,15],"sens":[0,1,10,17],"sensibl":[4,6,8],"sensit":17,"sensor":[10,14],"sent":[2,4,10,11,14,15,17],"sentenc":0,"sentiment":[0,14],"separ":[0,1,2,8,10,12,14,15],"sept":0,"septemb":0,"seq":5,"sequenc":[0,2,5,11,14,15,16],"sequenti":[5,16],"serfdom":17,"seri":[0,6],"serial":[0,2,4,7,10,14,16,17],"serialinterfac":[6,8],"seriou":[0,1],"serious":0,"serv":[0,1,2,6,7,8,10,12,13,14,15,17],"serve_nomadnet":5,"serve_path":2,"server":[0,1,2,4,5,6,7,10,11,12,14,15,17],"server_buffer_readi":2,"server_callback":2,"server_client_connect":2,"server_destin":2,"server_fil":2,"server_ident":2,"server_link":2,"server_loop":2,"server_message_receiv":2,"server_packet_receiv":2,"servic":[0,1,4,5,7,8,10,12,14,17],"session":[4,12,14,15],"set":[0,1,2,4,5,6,8,10,11,12,14,15,16,17],"set_default_app_data":11,"set_delivery_callback":[2,11],"set_link_closed_callback":[2,11],"set_link_established_callback":[2,11],"set_max_request_s":11,"set_packet_callback":[2,11],"set_proof_requested_callback":11,"set_proof_strategi":[2,11],"set_ratchet_interv":11,"set_remote_identified_callback":[2,11],"set_resource_callback":11,"set_resource_concluded_callback":[2,11],"set_resource_started_callback":[2,11],"set_resource_strategi":[2,11],"set_retained_ratchet":11,"set_timeout":[2,11],"set_timeout_callback":[2,11],"settl":0,"setup":[2,4,5,7,8,15],"sever":[0,4,5,10,11,12,15],"sf":15,"sh":8,"sha":[10,11,14],"sha256":[5,14,16],"shall":[0,9,14],"shallow":0,"shame":0,"shape":[0,10,17],"share":[0,1,2,4,10,11,12,14,15,17],"share_inst":15,"shared_instance_port":15,"shared_instance_typ":[11,15],"sharper":0,"shatter":0,"shelf":[14,16],"shell":[1,4,5,7,15,17],"shelter":1,"shift":[1,17],"shim":[0,5],"shine":17,"ship":[0,14,17],"shop":[2,17],"short":[0,6,7,8,14,15],"shortcom":0,"shorter":8,"shorthand":[8,15],"shortlog":5,"shot":4,"should":[0,1,2,4,5,8,10,11,12,14,15,17],"should_ingress_limit":2,"should_quit":2,"should_use_implicit_proof":11,"shout":17,"shove":1,"show":[0,4,5,15,17],"shown":[0,1,2,13],"shrink":0,"shut":[0,1,17],"side":[0,1,8,15,16],"sideband":[0,4,7,15],"sign":[0,1,7,8,10,11,14,15,17],"signal":[1,2,7,8,11,14,15,17],"signatur":[0,1,7,10,11,14,15,16,17],"signer":5,"signifi":14,"signific":10,"significantli":[8,11],"signingkei":5,"silent":[0,15],"silk":0,"similar":[0,1,2,4,5,6,8,11,12,15,16],"simpl":[0,2,4,5,6,11,12,14,15,16,17],"simpler":[5,8,10,16],"simplest":[8,14],"simpli":[0,1,2,4,5,6,8,10,12,13,14,15,17],"simplic":14,"simplifi":2,"simplyequip":6,"simul":[12,14],"simultan":[4,14],"sinc":[0,2,4,5,8,10,11,14,17],"sine":0,"sing":0,"singl":[0,1,2,4,5,8,10,11,14,15,16,17],"singular":14,"sit":[0,4,17],"site":[1,8,10,17],"situat":[0,4,5,6,8,10,14,15],"six":0,"size":[0,2,4,5,8,11,14,15],"size_str":2,"skeptic":0,"skill":[0,1],"skin":0,"skip":[2,5],"sky":7,"slap":17,"slave":17,"sleep":[2,4,15],"slice":[0,2,17],"slight":0,"slightli":[2,4,17],"slip":0,"slop":0,"sloppi":[0,17],"slot":0,"slottim":[8,15],"slow":[0,2,8,10,12,14,17],"slower":[0,8,11,14],"slowest":[0,11],"slyli":0,"small":[0,2,4,8,10,11,14,16,17],"smaller":[0,11],"smallest":4,"smear":0,"smooth":0,"snapshot":0,"sneez":0,"snippet":15,"snr":[2,11,15],"so":[0,1,2,4,5,6,8,9,10,11,12,13,14,15,16,17],"sober":0,"social":[0,1,4,17],"societi":17,"socket":[8,15,16,17],"sockpuppet":0,"soft":17,"softdevic":0,"softwar":[0,1,4,5,6,8,9,12,14,15,17],"solar":17,"soldier":0,"sole":[0,8],"solemn":0,"solicitud":0,"solid":[0,13],"solo":1,"solut":[0,1,12,14,15],"solv":[1,14,17],"some":[0,1,2,4,6,8,10,11,12,14,15,17],"some_program":5,"some_program_1":5,"some_remot":5,"somehow":0,"someon":[0,1,4,5,8,15,17],"someth":[0,1,5,8,10,14,17],"somethign":2,"sometim":[0,6,8,12,17],"somewhat":4,"somewher":[0,17],"soon":[5,11,15],"sort":[0,8,14,15],"soul":17,"sound":[0,12,17],"soundmodem":8,"sour":0,"sourc":[1,2,4,5,6,7,10,11,12,14,16,17],"source_":5,"sovereign":[1,4,14,17],"sovereignli":17,"sovereignti":[7,16],"space":[0,1,2,4,6,10,14,16,17],"spam":[4,8,14,15],"spammi":15,"span":[0,8,10,14],"spawn":[0,8,12],"spe":8,"speak":[0,1,13,17],"speaker":0,"spec":14,"speci":0,"special":[0,12,14,15],"specif":[0,1,2,5,6,7,8,10,11,15,16,17],"specifi":[0,1,2,4,5,6,8,10,11,14,15],"spectacularli":0,"spectrum":[0,8,14,17],"specul":0,"speech":0,"speed":[0,2,8,11,14,15,17],"spend":0,"spent":0,"spew":0,"sphere":17,"spin":0,"spinner":17,"spirit":[0,12],"split":2,"spoof":[5,17],"spread":[0,8,15],"spreadingfactor":8,"spring":0,"spun":0,"squelch":8,"ssh":[5,12,15],"ssid":8,"ssl":17,"stabil":[0,10,17],"stabl":[4,8,10,14,16],"stack":[2,4,10,11,12,14,15,16,17],"stackexchang":12,"stage":14,"stai":[2,8,14,15,17],"stake":[0,1],"stale":[10,11,15],"stale_grac":11,"stale_tim":11,"stall":0,"stamp":[8,11,15],"stanc":[1,17],"stand":[0,1,17],"standalon":[7,12],"standard":[1,5,6,7,8,12,14,15],"start":[0,2,5,6,7,8,10,11,12,14,15,17],"starter":0,"startup":[2,4,15],"stat":[5,11,15],"state":[0,1,2,7,10,17],"statement":0,"static":[4,5,8,11,17],"staticmethod":2,"station":8,"stationari":[10,15,17],"statist":[2,7,8,11,13],"stats_ignore_ident":5,"statu":[0,2,4,5,7,8,11,12,14,15,17],"statut":7,"statutori":0,"stderr":15,"stdin":[8,15],"stdio":16,"stdout":[2,5,8,15],"steel":17,"stem":13,"step":[0,2,4,5,6,17],"stewardship":17,"still":[0,1,2,4,5,8,10,14,15,17],"stock":[0,2],"stole":0,"stolen":0,"stone":17,"stop":[0,11,16,17],"stopbit":[2,8,15],"storag":[4,7,8,12,14,15,17],"store":[1,2,5,7,11,12,14,15],"store_tru":2,"stori":0,"storm":17,"str":[2,11],"straight":0,"straightforward":8,"strang":17,"stranger":17,"strangl":17,"strateg":10,"strategi":[0,1,7,8,11],"strawman":0,"stream":[0,1,2,11,12,14,15,17],"stream_id":[2,11],"street":17,"strength":[0,11,16,17],"strict":[1,17],"strictli":[0,8,14],"string":[0,2,11,17],"stringmessag":2,"strip":[0,1,5,17],"strong":[4,5,14,17],"stronger":[0,4],"strongli":4,"struct":2,"structur":[0,1,2,7,10,11,14,16,17],"studi":[0,1],"style":[0,5,8],"stylist":0,"sub":[2,8],"subclass":[2,11],"subcommand":5,"subdirectori":5,"subinterfac":8,"subject":[0,4,9,15,16,17],"sublicens":[0,9],"submit":[0,1],"subnet":[4,10],"subreddit":0,"subscrib":[4,15,17],"subsequ":[0,2,5,14],"subset":8,"subsid":8,"subsist":0,"substanc":7,"substant":0,"substanti":[0,1,9],"substitut":7,"substrat":[1,17],"subtl":17,"subtli":[0,17],"succe":[4,5,15],"succeed":[0,2,11],"succesfulli":10,"success":[0,1,4,5,8,11],"successful":11,"successfulli":[0,2,11,14],"sudden":0,"suddenli":[0,17],"sudo":[4,15],"sue":0,"suffer":10,"suffic":14,"suffici":[0,4,8,14,15,16],"suffix":2,"suggest":0,"suit":[0,1,4,6,12,14,15,17],"suitabl":[2,4,8,10,14,15,16],"sum":[0,17],"sun":0,"super":2,"superfici":0,"supersed":8,"superstructur":1,"supp":0,"suppli":[0,2,8,11,14,15,16],"supplier":4,"support":[0,1,2,4,5,7,8,10,11,12,14,15,16],"suprem":[0,1],"sure":[0,2,4,5,6,8,12,15],"surfac":[7,17],"surgic":0,"surprisingli":0,"surrend":1,"surround":[0,1,17],"surveil":[1,14,17],"surviv":[0,4,14,15,17],"suspend":1,"sustain":[0,17],"swim":1,"switch":[6,8,10,14,15,17],"sx1262":6,"sx1268":6,"sx1276":6,"sx1278":6,"sx1280":6,"sy":2,"syllog":0,"symbol":[0,5],"symlink":15,"symmetr":[11,14],"sync":5,"syncer":5,"synchron":[1,7,12,17],"syntax":7,"synthesi":0,"synthet":[0,17],"system":[0,1,2,4,5,6,7,8,9,10,11,13,14,16],"systemat":0,"systemctl":15,"systemd":15,"t":[0,1,2,4,5,8,10,11,14,15,17],"tabl":[0,4,8,10,14,15,17],"tablet":[0,4],"tackl":12,"tactic":0,"tag":[5,11],"taglin":0,"tail":8,"tailor":14,"take":[0,1,2,4,5,8,11,12,14,15,16,17],"taken":[0,2,5,14,15,17],"takeov":0,"talent":0,"talk":[0,12,17],"tamper":[1,5,17],"tangerin":2,"tangibl":0,"tantrum":0,"tap":[6,17],"tar":5,"target":[0,2,4,5,8,12,15,17],"target_hash":11,"target_host":8,"target_port":[8,15],"task":[5,15],"tast":0,"taught":17,"tcp":[0,4,6,7,10,14,15,16,17],"tcpclientinterfac":[0,4,6,8],"tcpinterfac":15,"tcpserverinterfac":[0,4,8],"tdata":2,"teach":[0,15,17],"teahous":[1,13],"team":[0,5],"teardown":[2,11],"teardown_reason":2,"tech":17,"technic":[0,1,5,12],"technician":17,"technolog":[0,1],"technologi":[0,4,10,17],"teffect":2,"telco":17,"telecom":17,"telemetri":[12,13],"telephon":[0,7],"telephoni":7,"televis":17,"tell":[0,2,4,8,10,17],"temperatur":14,"templat":[0,7],"temporari":[4,8,15],"temporarili":[0,8,10],"tempt":0,"ten":[0,14],"tenanc":17,"tenant":17,"tend":[0,8],"tenuou":17,"terabyt":0,"term":[0,1,4,8,10,14,17],"termin":[0,2,4,5,11,12,15],"terminolog":0,"terminologi":[10,14],"termux":4,"terrifi":17,"territori":1,"terror":0,"test":[0,4,5,12,14,15,17],"testimoni":1,"testnet":15,"tether":17,"text":[0,2,12,14,15],"textur":[0,17],"tfile":2,"tgz":[5,15],"thaler":0,"than":[0,1,2,4,5,8,10,11,12,13,14,15,16,17],"thank":[0,5],"theater":0,"theatr":0,"theatric":[0,1],"theft":0,"thei":[0,1,2,4,5,8,10,11,12,14,15,17],"theirs":0,"them":[0,1,2,4,5,6,8,10,12,14,15,16,17],"theme":5,"themself":0,"themselv":[0,1,5,8,10,15],"theoret":0,"theori":[0,1,17],"thereaft":14,"therefor":[0,4,14,16,17],"thereof":0,"thi":[1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17],"thin":0,"thing":[0,2,4,10,12],"think":[4,6,8,10,13,14,17],"thinner":0,"third":[0,1,5],"those":[0,1,4,10,14,15,17],"though":[0,1,4,8,10,14],"thought":[0,17],"thousand":[0,1,4,8,14,15,17],"thread":[0,1,2,5],"threat":[0,15],"three":[0,4,14,17],"threshold":8,"throough":8,"throttl":[8,10],"through":[0,2,4,5,6,7,8,10,11,12,14,15,16],"throughout":[10,14],"throughput":[0,1,11,12,14,16],"thrown":[11,17],"thu":[10,11,14],"ti":[2,10,14],"tickinput":0,"tickoutput":0,"tighten":17,"tightrop":17,"tild":15,"time":[0,1,2,4,5,6,7,8,10,11,12,13,14,15],"time_since_last":2,"timefram":1,"timeout":[2,11,15,17],"timeoutarg":2,"timer":5,"timescal":1,"timestamp":[2,5,11,14,17],"timestr":2,"tion":8,"titl":[0,5],"tl":17,"tmp":15,"tnc":[6,8,11,15,16],"to_fil":11,"todai":[0,1,14,17],"togeth":[0,6,10,14,15,17],"toggl":15,"token":[0,11,14,16],"tokyo":17,"told":[0,17],"toler":8,"tomorrow":17,"too":[0,2,10,17],"took":0,"tool":[0,1,4,5,6,7,8,10,12,14,15,16],"toolkit":[4,10],"top":[0,1,12,14,15,17],"topic":[4,14],"topograph":8,"topographi":[4,10,14,17],"topologi":[4,8,10,12,14,16,17],"torn":[11,15],"tort":9,"tortur":17,"torvald":1,"total":[0,5,11,14,15,16],"total_s":2,"touch":[8,17],"toward":[0,2,8,14],"tower":17,"toxic":[0,1],"trace":0,"track":[0,1,5,11,15,17],"track_phy_stat":11,"trade":[0,10,14],"tradit":[0,5,10,14,17],"tradition":1,"traffic":[0,2,4,8,10,11,14,15,17],"train":[0,9,17],"trajectori":0,"transceiv":[4,6,8,12,14,16],"transfer":[0,2,5,11,12,14,15,16],"transfer_s":2,"transform":[0,16],"transient":17,"transistor":17,"transit":0,"translat":[7,10],"transmiss":[4,8,11,14,17],"transmit":[0,2,5,8,14,17],"transmitt":17,"transpar":[0,5,6,8,10,14,15],"transport":[0,1,2,4,5,7,8,11,12,15,16,17],"transport_en":11,"transport_ident":15,"trap":7,"travel":[1,17],"travers":[1,4,8,11,14,17],"treat":[0,1,5,10,14,17],"tree":[0,1,5],"tremend":10,"tri":[0,2],"triad":7,"trigger":8,"trip":[2,11,15],"trivial":[14,16],"troll":0,"troubl":17,"true":[0,1,2,4,8,11,12,15,17],"truli":[0,6,14,17],"truncat":[11,14,15],"truncated_hash":11,"truncated_hashlength":[2,11],"trust":[0,1,4,5,7,8,10,14,15],"trustless":[7,14,16],"trustworthi":[10,15],"truth":[0,5],"try":[2,5,7,8,10,11,12],"ttime":2,"ttransfer":2,"ttyacm0":8,"ttyusb0":[2,8,15],"ttyusb1":8,"ttyusb2":8,"tui":7,"tun":[6,8],"tun0":8,"tune":7,"tunnel":[4,8,10,14,16,17],"tupl":11,"turbo":0,"turn":[0,1,2,8,15,17],"turnaround":8,"tutori":4,"twelv":0,"two":[1,2,5,6,7,8,10,11,14,15],"tx":[8,15],"txb":2,"txp":15,"txpower":8,"txt":[5,15],"txtail":[8,15],"type":[0,2,4,7,8,10,11,15],"typeerror":11,"typic":[5,8,10,14],"tyrant":17,"u":[0,14,15,17],"ubiqu":6,"ubuntu":[7,15],"uci":4,"udp":[7,10,14,15,16],"udpinterfac":[0,8],"uhf":[12,15,16],"ui":[12,17],"ultim":[4,14,17],"umsgpack":2,"unaid":0,"unanswer":0,"unapologet":0,"unauthor":0,"unavail":[0,5],"unblackhol":15,"unblackhole_ident":11,"unblock":15,"unbound":[0,17],"uncar":17,"uncencrypt":2,"uncentraliz":7,"uncertainti":0,"unchang":[0,10],"uncheck":0,"uncomfort":0,"uncontamin":0,"uncontroversi":0,"uncoordin":[4,17],"under":[0,1,5,8,11,13,14,15,16,17],"underli":[2,8,10,11,14,16],"undermin":[0,17],"underneath":17,"undersea":17,"understand":[0,1,4,7,8,10,11,15,16,17],"understood":[0,17],"underwai":4,"underwear":17,"undetect":0,"unencrypt":[2,11,14],"unencumb":0,"unenforc":0,"unequivoc":14,"unexamin":0,"unexcit":0,"unexplor":10,"unfair":0,"unforeseen":1,"unforg":[10,16],"unfortun":[0,4],"unfre":0,"unhealthi":0,"unicod":5,"unicode_icon":5,"unidentifi":2,"unidirect":2,"unifi":[10,14],"uniform":0,"uninform":1,"uninterest":2,"uniqu":[2,8,10,11,14,15,16,17],"unison":0,"unit":[0,1,2,4,11,15],"univers":17,"unix":[5,11],"unknow":0,"unknown":[0,2,8,10,11,14,15],"unlawfulli":0,"unlearn":17,"unless":[2,4,8,10,11,14],"unlicens":[0,14],"unlik":[1,5,14],"unlock":15,"unmask":0,"unmeasur":0,"unmedi":1,"unnecessari":8,"unorganis":10,"unown":0,"unpack":[2,11],"unpackb":2,"unpaid":17,"unplug":[15,17],"unpreced":0,"unprofession":0,"unprotect":0,"unproven":0,"unreach":0,"unread":0,"unrecover":[2,15],"unrel":0,"unreli":8,"unrestrict":0,"unreview":0,"unsatur":1,"unset":14,"unsubstanti":0,"unsupport":11,"until":[2,4,8,11],"untrust":[5,15],"untrustworthi":17,"unus":15,"unverifi":[0,15],"unwant":[14,15],"unwrap_or":0,"unwritten":0,"up":[0,1,2,4,5,6,8,10,11,12,14,15,16,17],"updat":[0,1,2,4,5,11,12,14,15,17],"upgrad":[0,4,11,14],"upkeep":8,"upload":5,"upon":[0,1,2,8,14],"upset":2,"upstream":[0,1,5,12,15],"uptim":[0,17],"urandom":[14,16],"urgenc":[0,1],"urgent":17,"uri":12,"url":[1,5,15,17],"urwid":12,"us":[1,2,5,6,7,8,9,10,11,17],"usabl":[5,8,14],"usag":[5,7,8,11,12,13,15],"usb":[1,6,14,15],"useabl":14,"useless":[1,17],"user":[0,1,2,4,5,8,10,12,14,15,16,17],"user_input":2,"userland":16,"usernam":[0,17],"usernameher":15,"usr":[8,15],"usual":[0,4,8,10],"usurp":0,"utf":2,"util":[2,6,7,8,14,17],"utilis":[2,4,8,11,12,14,15,16],"ux":12,"v":[5,7,15],"v4":0,"vaccuum":0,"valid":[0,1,2,4,7,8,10,11,14,15,17],"vallei":0,"valu":[0,1,2,4,5,8,11,14,15,17],"valuabl":[0,1,5,6,13,17],"valueerror":[2,11],"vanish":[0,17],"vanishingli":[0,17],"var":5,"vari":[4,8,14,15],"variabl":[2,4,5,11],"varianc":0,"variant":0,"variat":0,"varieti":[8,12,14,15,16],"variou":[0,2,4,8,10,11,12,14,15,16],"vast":[0,1,4,14,17],"vastli":10,"vau001480196":0,"vc":0,"ve":10,"vector":0,"vehicl":[0,8],"veloc":[0,1],"vendor":[0,2,6,16],"ventur":17,"venu":1,"verbatim":0,"verbos":[5,11,15],"verdict":7,"veri":[0,1,4,5,6,8,10,11,12,13,14,15,16,17],"verif":[0,1,7,10,11,12,14,15,17],"verifi":[0,1,2,4,7,8,10,11,14,15,16,17],"versa":16,"version":[0,1,2,4,5,14,15,17],"versu":7,"vet":0,"vhf":[12,14,16],"vi":[5,7],"via":[1,4,5,6,8,10,12,13,14,15,16,17],"viabl":10,"vice":16,"video":17,"view":[1,4,5,8,12,13,14,15],"viewabl":5,"vim":5,"vindic":0,"violat":[0,8],"violenc":0,"violent":0,"viral":0,"virtu":0,"virtual":[4,6,8,10,14,15,16],"virtuou":17,"visibl":[0,1,2,5,8],"visibli":0,"visual":[0,5,14,17],"vital":17,"vocabulari":0,"voic":[0,1,7,13,17],"voicemail":12,"void":7,"volum":0,"volunt":4,"voluntari":4,"vouch":17,"vpn":[10,17],"vport":8,"vulner":10,"vv":15,"vvv":4,"w":[5,15],"wa":[1,2,5,6,7,8,10,11,14,15,16,17],"wai":[0,1,2,5,7,8,10,11,12,14,15,17],"wait":[0,2,4,8,12,14,15,17],"waiv":0,"walk":17,"wall":[0,17],"wander":17,"want":[0,1,2,4,5,8,10,12,13,14,15,17],"wantedbi":15,"warhol":0,"warn":[0,15],"warrant":16,"warranti":9,"wash":17,"wasm":0,"wast":[0,8,10,13,17],"watch":0,"wave":[0,6,17],"wb":2,"we":[0,1,2,4,6,8,10,13,14,17],"weaken":14,"weapon":[0,1,17],"weaponis":0,"wear":[0,17],"weather":17,"weav":17,"web":[0,4,12,17],"websit":[0,4,8,17],"week":0,"weekdai":0,"weekend":0,"weigh":17,"weight":[0,1,5,15,17],"weird":0,"welcom":[0,1],"well":[0,1,5,6,8,10,11,12,13,14,15,16,17],"went":2,"were":[0,1,2,5,12,17],"what":[1,2,4,5,7,8,10,11,14,15,17],"whatev":[0,10,11,14],"whatsoev":0,"wheel":[4,5],"when":[0,1,2,4,5,6,8,10,11,12,14,15,17],"whenev":[0,2,11,14],"where":[0,1,4,5,6,7,8,10,11,12,14,15,17],"whereupon":14,"wherev":17,"whether":[0,2,4,5,8,9,10,11,14,17],"which":[1,2,4,5,7,8,9,10,11,14,15,16,17],"while":[0,1,2,4,5,6,8,10,11,12,14,15,16,17],"whim":17,"whitelist":14,"whl":[4,5],"who":[1,4,5,7,8,10,14,15,17],"whole":[7,15,17],"wholesal":0,"whom":[0,9,17],"whose":[0,15,17],"why":[1,7,17],"wide":[0,4,5,6,8,10,12,14,15,16],"wider":[0,4,8,10,14,15],"wield":[0,1],"wifi":[4,7,8,10,12,14,15,16,17],"wikipedia":12,"wild":[5,15,17],"wildcard":[2,5],"wilder":17,"wildli":0,"willi":0,"willing":[0,15],"win":0,"win_amd64":0,"window":[0,7,8,12,15],"windowsil":17,"wine":7,"wipe":15,"wire":[0,6,7,8,12,16,17],"wireless":[6,10],"wirelessli":8,"wish":[0,2,8,14,15,17],"witchcraft":0,"withhold":0,"within":[0,1,2,4,5,8,10,11,14,17],"without":[0,2,4,5,6,7,8,9,10,12,14,15,16,17],"wlan0":8,"wolf":6,"won":2,"word":[0,1,4,17],"wore":0,"work":[1,4,6,7,8,10,12,14,15,16],"workabl":10,"workflow":7,"workspac":0,"world":[0,1,4,6,8,10,12,15,16,17],"worldwid":0,"worri":[0,10],"wors":0,"worst":0,"worth":[0,1,4],"worthless":0,"would":[0,1,5,8,11,14,15,17],"wrap":5,"write":[0,1,2,4,5,6,8,11,12,14,15,17],"write_timeout":2,"writer":[0,2,11],"written":[0,2,5,14,16,17],"wrong":[0,2,4,8,17],"wrote":[0,2,8],"x":[0,5,11,14,15],"x25519":[14,16],"x86_64":[0,5],"xenon":2,"xonxoff":2,"y":[0,2,5],"ye":[0,4,5,8,14,15,17],"year":[0,14,17],"yearn":0,"yet":[0,1,2,8,14,17],"yggdrasil":8,"yi":2,"yield":0,"you":[0,1,2,4,5,6,7,8,10,11,12,13,14,15,16,17],"young":0,"your":[0,1,2,5,6,7,8,10,12,13,14,16,17],"yourself":[0,1,4,14,15,16,17],"z":2,"zarya":0,"zen":[0,7,16],"zero":[0,7,8,11,12,16],"zi":2,"zim":12,"zip":5,"zone":[0,1,14],"zshrc":4},"titles":["Brandolini\u2019s Reference","Distributed Development","Code Examples","An Explanation of Reticulum for Human Beings","Getting Started Fast","Git Over Reticulum","Communications Hardware","Reticulum Network Stack Manual","Configuring Interfaces","Reticulum License","Building Networks","API Reference","Programs Using Reticulum","Support Reticulum","Understanding Reticulum","Using Reticulum on Your System","What is Reticulum?","Zen of Reticulum"],"titleterms":{"":0,"0":6,"1":[0,6],"2":0,"25":8,"A":[0,17],"And":0,"Beings":3,"But":0,"By":0,"For":[0,17],"In":[0,17],"No":0,"Not":[0,10,17],"Of":[0,1,7,17],"On":0,"Or":[0,17],"That":0,"The":[0,1,5,14,15,17],"These":0,"To":[0,17],"With":[4,5],"abil":17,"access":[5,14],"actual":0,"ad":4,"addendum":0,"address":[10,17],"administr":12,"agenc":[0,17],"agent":0,"alias":5,"an":3,"analysi":0,"anchor":17,"android":4,"announc":[2,8,14,17],"answer":0,"api":11,"ar":0,"architectur":[1,17],"archiv":1,"argument":0,"arm64":4,"artifact":1,"assist":0,"attribut":[0,5],"author":[0,5],"auto":8,"autom":[8,15],"automat":5,"ax":8,"backbon":[4,8],"bandwidth":17,"base":[4,6],"basic":14,"beam":6,"bind":5,"blackhol":15,"block":8,"board":6,"bookworm":4,"bootstrap":4,"bound":0,"brandolini":0,"brief":0,"broadcast":2,"brows":12,"browser":12,"buffer":2,"build":[4,10],"burst":8,"byte":17,"can":16,"carrier":17,"case":0,"center":[1,17],"channel":2,"chat":12,"citizenship":0,"claim":0,"clean":0,"client":8,"cloud":17,"code":[0,2,14],"coexist":0,"columba":12,"combin":6,"command":5,"commit":5,"common":[0,8],"commun":6,"compon":12,"compos":1,"concept":10,"conceptu":14,"conclus":0,"condit":0,"configur":[5,8,15],"conform":0,"connect":[4,8,10,12],"consequ":0,"consider":[8,10],"content":7,"context":0,"contribut":4,"control":8,"copi":0,"copyright":0,"cost":17,"creat":[4,5,6,14],"creation":5,"creator":5,"cryptograph":[5,14],"current":[14,16],"custom":[2,4,5,8],"data":15,"date":0,"death":17,"debian":4,"decentr":17,"deck":6,"defenc":0,"delus":0,"depend":4,"design":17,"destin":[5,8,10,14],"detail":14,"develop":[1,4],"devic":[6,12,16],"dichotomi":0,"directli":0,"disclos":0,"disconnect":17,"discov":15,"discover":8,"discoveri":8,"distribut":[0,1,4],"do":0,"document":5,"doe":[0,16],"domain":17,"donat":13,"dozen":0,"echo":[2,6],"elong":0,"emerg":17,"empti":5,"enabl":[5,8],"encrypt":17,"engin":0,"entrypoint":4,"environ":17,"establish":14,"ethernet":6,"ethic":17,"evalu":0,"exampl":[2,5,8],"exist":[0,17],"expand":0,"explan":3,"express":0,"fabric":17,"fair":0,"fallaci":17,"fals":0,"fast":4,"featur":17,"feedback":13,"ferment":0,"filesync":12,"filetransf":2,"find":4,"finish":17,"fix":15,"flasher":12,"flow":17,"fluenci":0,"fork":5,"form":5,"format":[5,14],"forward":17,"foundat":0,"fragil":0,"free":0,"freedom":0,"from":[0,17],"function":14,"further":14,"futur":14,"gener":0,"get":[4,14],"git":[5,12],"global":4,"goal":14,"grade":17,"grant":0,"group":5,"guid":0,"ha":0,"happen":0,"hardwar":6,"harm":17,"headcount":0,"health":[0,4],"heltec":6,"heterogen":10,"hierarchi":5,"highlight":5,"histori":0,"host":4,"hostil":17,"human":[3,17],"i":[0,16,17],"i2p":8,"idea":0,"ident":[5,14,17],"identif":2,"ii":0,"iii":0,"illus":17,"implement":[0,16],"implic":14,"improv":15,"includ":[4,15],"independ":17,"indic":7,"individu":0,"influenc":0,"infrastructur":[0,1,4,17],"ingress":8,"instal":[4,6],"instanc":[4,10],"institut":0,"intent":0,"interact":5,"interfac":[2,4,8,12,14,15,16,17],"intermediari":1,"internet":4,"interregnum":1,"introduct":14,"introductori":10,"ip":17,"issu":4,"iv":0,"j":12,"kei":14,"kiss":8,"launder":0,"layer":0,"legal":0,"liber":17,"licens":[0,9],"like":0,"lilygo":6,"limit":[8,17],"line":[0,5,6],"link":[2,14],"list":15,"listen":8,"local":15,"locat":5,"long":1,"look":0,"lora":8,"lora32":6,"lunar":4,"lxmf":12,"lxmfy":12,"lxst":12,"machin":0,"maco":4,"mad":0,"manag":[5,15],"manual":[5,7],"matter":0,"mean":0,"mechan":14,"medium":17,"merit":17,"meshchatx":12,"messag":12,"method":[0,5],"micron":12,"minim":2,"mirror":5,"mix":4,"mode":8,"modem":6,"modem73":12,"modul":12,"monetari":0,"most":0,"motiv":14,"movement":0,"multi":8,"name":[14,15,17],"network":[0,4,5,7,10,12,14],"new":[0,8],"node":[5,10,12,14,17],"nomad":[5,12,17],"note":4,"obtain":5,"offer":16,"offlin":5,"open":[0,17],"opencom":6,"openwrt":4,"option":8,"origin":1,"other":0,"output":0,"over":[1,4,5,12],"overal":0,"overview":[10,14],"packet":[6,14],"page":[5,12],"paramet":[5,8],"parser":12,"partylin":12,"path":8,"pattern":[0,17],"perform":0,"permiss":5,"persist":0,"person":[4,17],"phone":12,"physic":17,"pi":4,"pipe":8,"place":0,"platform":[1,4],"port":15,"portabl":17,"posit":0,"possibl":0,"post":17,"power":17,"predict":0,"prerequisit":5,"presenc":17,"present":0,"preserv":17,"primit":[1,14],"principl":[0,17],"prioritis":14,"prn":0,"program":[4,12,15],"project":0,"propag":14,"properti":0,"propos":5,"protect":0,"protocol":[1,12,14,17],"proven":0,"provid":13,"public":[4,14,17],"publish":[12,15],"pure":4,"purpos":0,"python":4,"question":0,"queue":8,"radio":[4,6],"rak4631":6,"raspberri":4,"rate":8,"reach":14,"realiti":0,"reason":0,"recognit":0,"recycl":0,"refer":[0,11,14,16],"relai":12,"releas":5,"remot":[5,8,12,15],"ren":12,"repositori":5,"request":[2,8],"rescu":0,"resolv":[0,4],"resourc":[12,14],"respons":[0,2,4],"restor":1,"restrict":0,"ret":4,"retibb":12,"reticul":12,"reticulum":[0,3,4,5,6,7,9,12,13,14,15,16,17],"retipedia":12,"risc":4,"rn":12,"rncp":15,"rngit":[5,15],"rnid":15,"rnmon":12,"rnode":[6,8],"rnodeconf":15,"rnpath":15,"rnprobe":15,"rnsd":15,"rnsh":15,"rnstatu":15,"rnx":15,"road":1,"roam":17,"role":0,"room":0,"rrc":12,"rule":14,"scarciti":17,"scope":0,"secur":8,"serial":[6,8,15],"serv":5,"server":8,"servic":15,"setup":14,"shell":12,"short":5,"sideband":12,"sign":5,"signal":0,"signatur":5,"sky":17,"sourc":[0,15],"sovereignti":[1,17],"specif":[4,14],"stack":7,"standalon":4,"standard":0,"start":[1,4],"state":5,"statist":5,"statu":16,"statut":0,"storag":5,"store":17,"strategi":4,"structur":5,"substanc":0,"substitut":0,"support":[6,13],"suprem":6,"surfac":0,"synchron":5,"syntax":5,"system":[12,15,17],"systemwid":15,"t":6,"t114":6,"t3s3":6,"tabl":7,"tcp":8,"telephon":12,"telephoni":12,"templat":5,"thi":0,"through":[1,17],"time":17,"tool":17,"translat":0,"transport":[10,14],"trap":0,"triad":0,"trust":17,"trustless":10,"try":4,"tui":12,"tune":8,"two":0,"type":[5,6,14,16],"ubuntu":4,"udp":8,"uncentraliz":17,"understand":14,"unsign":6,"us":[0,4,12,14,15,16],"usag":[6,14],"userspac":15,"util":[4,5,12,15],"v":[0,4],"v1":6,"v2":6,"v3":6,"v4":6,"valid":5,"verdict":0,"verif":5,"verifi":5,"versu":0,"vi":0,"voic":12,"void":0,"wa":0,"wai":4,"what":[0,16],"where":16,"which":0,"who":0,"whole":0,"why":0,"wifi":6,"window":4,"wine":0,"wire":14,"without":1,"work":[0,5,17],"workflow":[1,5],"x":6,"xl":6,"your":[4,15],"zen":17,"zero":17}}) \ No newline at end of file diff --git a/docs/manual/software.html b/docs/manual/software.html index d705c5bd..60673be9 100644 --- a/docs/manual/software.html +++ b/docs/manual/software.html @@ -7,7 +7,7 @@ - Programs Using Reticulum - Reticulum Network Stack 1.5.1 documentation + Programs Using Reticulum - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
    • API Reference
    • @@ -264,96 +265,114 @@

      Programs Using Reticulum

      -

      This chapter provides a non-exhaustive list of notable programs, systems and application-layer -protocols that have been built using Reticulum.

      -

      These programs will let you get a feel for how Reticulum works. Most of them have been designed -to run well even over slow networks based on LoRa or packet radio, but all can also be used over fast -links, such as local WiFi, wired Ethernet, the Internet, or any combination.

      -

      As such, it is easy to get started experimenting, without having to set up any radio -transceivers or infrastructure just to try it out. Launching the programs on separate -devices connected to the same WiFi network is enough to get started, and physical -radio interfaces can then be added later.

      -
      -

      Programs & Utilities

      -

      Many different applications using Reticulum already exist, serving a wide variety of purposes -from day-to-day communication and information sharing to systems administration and tackling -advanced networking and communications challenges.

      -

      Development of Reticulum-based applications and systems is ongoing, so consider this list -a non-exhaustive starting point of some of the options available. With a bit of searching, -primarily over Reticulum itself, you will find many more interesting things.

      -
      -

      Remote Shell

      -

      The rnsh program lets you establish fully interactive -remote shell sessions over Reticulum. It also allows you to pipe any program to or from a -remote system, and is similar to how ssh works. The rnsh program is very efficient, and -can facilitate fully interactive shell sessions, even over extremely low-bandwidth links, -such as LoRa or packet radio.

      -

      In addition to the default, fully interactive terminal mode, -for extremely limited links, rnsh offers line-interactive mode, allowing you to interact -with remote systems, even when link throughput is counted in a few hundreds of bits per second.

      -
      +

      This chapter provides a non-exhaustive list of notable programs, systems and application-layer protocols that have been built using Reticulum.

      +

      Many different applications using Reticulum already exist, serving a wide variety of purposes from day-to-day communication and information sharing to systems administration and tackling advanced networking and communications challenges.

      +
      +

      Tip

      +

      For ease of discovery while reading this manual over the web or as an e-book, links provided in this chapter primarily point to repositories and pages located on internet servers. In many cases, these are public web mirrors, with the upstream repositories residing on Reticulum nodes. For the latest source, updates and information regarding any project, be sure to check their Nomad Network or rngit nodes.

      +
      +

      These programs will let you get a feel for how Reticulum works. Most of them have been designed to run well even over slow networks based on LoRa or packet radio, but all can also be used over fast links, such as local WiFi, wired Ethernet, the Internet, or any combination.

      +

      As such, it is easy to get started experimenting, without having to set up any radio transceivers or infrastructure just to try it out. Launching the programs on separate devices connected to the same WiFi network is enough to get started, and physical radio interfaces can then be added later.

      +

      Development of Reticulum-based applications and systems is ongoing, so consider this list a non-exhaustive starting point of some of the options available. With a bit of searching, primarily over Reticulum itself, you will find many more interesting things.

      +
      +

      Browsing & Publishing

      +

      In addition to the programs listed in this section, other Nomad Network clients include:

      +

      Nomad Network

      -

      The terminal-based program Nomad Network -provides a complete encrypted communications suite built with Reticulum. It features -encrypted messaging (both direct and delayed-delivery for offline users), file sharing, -and has a built-in text-browser and page server with support for dynamically rendered pages, -user authentication and more.

      -_images/nomadnet_3.png +

      The terminal-based program Nomad Network provides a complete encrypted communications suite built with Reticulum.

      +_images/nomadnet_6.webp -

      Nomad Network is a user-facing client -for the messaging and information-sharing protocol LXMF.

      +

      It features encrypted LXMF messaging (both direct and delayed-delivery for offline users), file sharing, and has a built-in text-browser and page server with support for dynamically rendered pages, user authentication and more. It also includes an RRC client and a suite of network utilities.

      +
      +
      +

      Ren Browser

      +

      Ren Browser is a modern, standalone browser for Nomad Network using the Reticulum-Go implementation. The project is actively being developed, and should be considered alpha level software, but much of the functionality is already working. If you want to help expanding the ecosystem, this is an excellent project to take a look at.

      +_images/ren_browser.webp + +

      Ren Browser is great example of an application aiming for true, seamless interoperability with the existing software ecosystem. It can operate fully standalone using it’s own embedded Go implementation of Reticulum, or seamlessly utilise a shared RNS instance already running on the system.

      RNS Page Node

      -

      RNS Page Node is a simple way to serve pages and files to any other Nomad Network compatible client. Drop-in replacement for NomadNet nodes that primarily serve pages and files.

      +

      RNS Page Node is a simple way to serve pages and files to any other Nomad Network compatible client. Drop-in replacement for NomadNet nodes that primarily serve pages and files.

      Retipedia

      -

      You can host the entirity of Wikipedia (or any .zim) file to other Nomad Network clients using Retipedia.

      +

      You can host the entirity of Wikipedia, StackExchange or any other .zim file, to Nomad Network clients using Retipedia.

      +_images/retipedia.webp +
      +
      +

      Git Over Reticulum

      +

      The included rngit system provides a fully distributed solution for managing, hosting, collaborating on and interacting with Git repositories over Reticulum.

      +_images/rngit.webp +
      +
      +
      +

      Messaging & Voice

      Sideband

      -

      If you would rather use an LXMF client with a graphical user interface, you can take -a look at Sideband, which is available for Android, -Linux, macOS and Windows. Sideband is an advanced LXMF and LXST client, and a multi-purpose Reticulum -utility, with features and functionality targeted at advanced users.

      -_images/sideband_devices.webp +

      Sideband is a technical LXMF and LXST client, for Android, Linux, macOS and Windows. It also serves as a multi-purpose Reticulum utility, with features and functionality targeted at advanced users.

      +_images/sideband_devices.webp -

      Sideband allows you to communicate with other people or LXMF-compatible -systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, Encrypted QR -Paper Messages, or anything else Reticulum supports.

      -

      It also interoperates with all other LXMF clients, and provides advanced features such as voice messaging, -real-time voice calls, file attachments, private telemetry sharing, and a full -plugin system for expandability.

      +

      Sideband allows you to communicate with other people or LXMF-compatible systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, Encrypted QR Paper Messages, or anything else Reticulum supports.

      +

      It interoperates with all other LXMF clients, and provides advanced features such as PTT and voice messaging, real-time voice calls, file attachments, private telemetry sharing, and a full plugin system for expandability.

      -
      -

      MeshChatX

      -

      A Reticulum MeshChat fork from the future, with the goal of providing everything you need for Reticulum, LXMF, and LXST in one beautiful and feature-rich application. This project is separate from the original Reticulum MeshChat project, and is not affiliated with the original project, but is a much more up-to-date, comprehensive and well-maintained fork.

      -_images/meshchatx.webp +
      +

      MeshChatX

      +

      MeshChatX is an all-in-one Reticulum client with messaging, calling, and a NomadNet browser, providing everything you need for Reticulum, LXMF, and LXST in one beautiful and feature-rich application.

      +_images/meshchatx.webp -

      Features include full LXST support, custom voicemail, phonebook, contact sharing, and ringtone support, multi-identity handling, modern UI/UX, offline documentation, expanded tools, page archiving, integrated maps, telemetry and improved application security.

      +

      Features include full LXST support, custom voicemail, phonebook, contact sharing, ringtone support, multi-identity handling, modern UI/UX, offline documentation, expanded tools, page archiving, integrated maps, telemetry and improved application security.

      +
      +

      Columba

      +

      Columba is a simple and familiar LXMF messaging app Android, built with a native Android interface and Material Design 3. It also includes LXST voice call functionality, and a mobile Nomad Network page browser.

      +_images/columba.webp + +
      +
      +

      Ren TUI

      +

      Ren TUI is an early prototype terminal LXMF client for Reticulum built with Odin on librns (Reticulum-Go). It aims for NomadNet-like messaging/browsing without urwid or ncurses.

      +_images/rentui.webp + +
      +
      +
      +

      Chat

      Reticulum Relay Chat

      Reticulum Relay Chat is a live chat system built on top of the Reticulum Network Stack. It exists to let people talk to each other in real time over Reticulum without dragging in message databases, synchronization engines, or architectural commitments they did not ask for.

      -

      The rrcd program provides a functional, reference RRC hub-server daemon implementation. RRC user clients include rrc-gui and rrc-web.

      +_images/rrc.webp

      RRC is closer in spirit to IRC than to modern “everything platforms.” You connect, you join a room, you talk, and then you leave. If you were present, you saw the conversation. If you were not, the conversation did not wait for you. This is not an accident. This is the entire design.

      +

      The rrcd program provides a functional, reference RRC hub-server daemon implementation. RRC user clients include:

      +

      RetiBBS

      -

      RetiBBS is a bulletin board system implementation for Reticulum networks.

      +

      RetiBBS is an old-school bulletin board system implementation for Reticulum networks.

      _images/retibbs.webp

      RetiBBS allows users to communicate through message boards in a secure manner.

      -
      -

      RBrowser

      -

      The rBrowser program is a cross-platform, standalone, web-based browser for exploring NomadNetwork Nodes over Reticulum Network. It automatically discovers NomadNet nodes through network announces and provides a user-friendly interface for browsing distributed content with Micron markup support.

      -_images/rbrowser.webp - -

      Includes useful features like automatic listening for announce, adding nodes to favorites, browsing and rendering any kind of NomadNet links, downloading files from remote nodes, a unique local NomadNet Search Engine and more.

      +
      +

      Voice & Telephony

      +

      In addition to the programs listed in this section, other LXST voice clients include:

      +

      Reticulum Network Telephone

      The rnphone program, included as part of the LXST package is a command-line Reticulum telephone utility and daemon, that allows building physical, hardware telephones for LXST and Reticulum, as well as simply performing calls via the command line.

      @@ -361,34 +380,75 @@ plugin system for expandability.

      It supports interfacing directly with hardware peripherals such as GPIO keypads and LCD displays, providing a modular system for building secure hardware telephones.

      +
      +

      Partyline

      +

      Partyline is a group voice application for Reticulum, built on LXST, inspired by Mumble.

      +_images/partyline.webp + +

      It provides both realtime group voice over any Reticulum transport capable of >6 kilobits per second, LXST dial-in support, listen-only music/broadcasting rooms, and many other useful functions.

      +

      LXST Phone

      -

      The LXST Phone program is a cross-platform desktop application for performing LXST voice calls over Reticulum.

      +

      The LXST Phone program is a cross-platform desktop application for performing LXST voice calls over Reticulum. It supports various advanced features such as SAS verification, peer blocking, rate limiting, encrypted call history storage and contact management.

      _images/lxst_phone.webp -

      It supports various advanced features such as SAS verification, peer blocking, rate limiting, encrypted call history storage and contact management.

      -
      -

      LXMFy

      -

      LXMFy is a comprehensive and advanced bot creation framework for LXMF, that allows building any kind of automation or bot system running over LXMF and Reticulum. Bot implementations exist for Home Assistant control, LLM integrations, and various other purposes.

      -
      -

      LXMF Interactive Client

      -

      LXMF Interactive Client is a feature-rich, terminal-based LXMF messaging client with many advanced features and an extensible plugin architecture.

      +
      +

      System Administration

      +
      +

      Remote Shell

      +

      The included rnsh program lets you establish fully interactive +remote shell sessions over Reticulum. It also allows you to pipe any program to or from a +remote system, and is similar to how ssh works. The rnsh program is very efficient, and +can facilitate fully interactive shell sessions, even over extremely low-bandwidth links, +such as LoRa or packet radio.

      +

      In addition to the default, fully interactive terminal mode, for extremely limited links, +rnsh offers line-interactive mode, allowing you to interact with remote systems, even +when link throughput is counted in a few hundreds of bits per second.

      RNS FileSync

      -

      The RNS FileSync program enables automatic file synchronization between devices without requiring central servers, internet connectivity, or cloud services. It works over any network medium supported by Reticulum, including radio, LoRa, WiFi, or the internet, making it ideal for off-grid, privacy-focused, and resilient file sharing.

      +

      The RNS FileSync program enables automatic file synchronization between devices without requiring central servers, internet connectivity, or cloud services. It works over any network medium supported by Reticulum, including radio, LoRa, WiFi, or the internet, making it ideal for off-grid, privacy-focused, and resilient file sharing.

      +
      +
      +
      +

      Utilities & Components

      +
      +

      Modem73

      +

      MODEM73 and its companion Modem73Interface is an open source software modem that works with any HF, VHF, or UHF radio capable of 2400 Hz of bandwidth. All you need is a sound card and audio cable for your radio.

      +_images/modem73.webp + +
      +
      +

      LXMFy

      +

      LXMFy is a comprehensive and advanced bot creation framework for LXMF, that allows building any kind of automation or bot system running over LXMF and Reticulum. Bot implementations exist for Home Assistant control, LLM integrations, and various other purposes.

      Micron Parser JS

      Micron Parser JS is the JavaScript-based parser for the Micron markup language, that most web-based Nomad Network browsers use. If you want to make utilities or tools that display Micron pages, this library is essential.

      +
      +

      Reticulated

      +

      Reticulated is a Reticulum Network simulator that spawns live, interactive Reticulum instances controllable from a node-based Web UI.

      +_images/reticulated.webp + +

      You can create networks of any topology and set bitrate, MTU, and configure path loss and propagation behavior. It provides a top-down view to a live network. You can connect any Reticulum application to the simulated network. It also has built in utilities like a basic LXMF chat function and Resource transfer included.

      +

      RNMon

      RNMon is a monitoring daemon designed to monitor the status of multiple RNS applications and push the metrics to an InfluxDB instance over the influx line protocol.

      +
      +

      Device Flashers

      +

      In addition to the included command-line rnodeconf flasher, several community-provided RNode device flashers exist:

      + +

      Several programs, such as Sideband and MeshChatX also include built-in device flashers that can be used fully offline.

      +

      Protocols

      A number of standard protocols have emerged through real-world usage and testing in the Reticulum community. While you may sometimes want to use completely custom protocols and implementations when writing Reticulum-based software, using these protocols provides application developers with an easy way to implement advanced functionality quickly and effortlessly. Using them also ensures compatibility and interoperability between many different client applications, creating an open communications ecosystem where users are free to choose the applications that suit their needs, while remaining connected to everyone else.

      @@ -398,8 +458,8 @@ plugin system for expandability.

      LXMF is efficient enough that it can deliver messages over extremely low-bandwidth systems such as packet radio or LoRa. Encrypted LXMF messages can also be encoded as QR-codes or text-based URIs, allowing completely analog paper message transport.

      Using Propagation Nodes, LXMF also offer a way to store and forward messages to users or endpoints that are not directly reachable at the time of message emission.

      -
      -

      LXST

      +
      +

      LXST

      LXST is a simple and flexible real-time streaming format and delivery protocol that allows a wide variety of applications, while using as little bandwidth as possible. It is built on top of Reticulum and offers zero-conf stream routing, end-to-end encryption and Forward Secrecy, and can be transported over any kind of medium that Reticulum supports. It currently powers real-time voice and telephony applications over Reticulum.

      @@ -412,11 +472,11 @@ plugin system for expandability.

      Interface Modules & Connectivity Resources

      This section provides a list of various community-provided interface modules, guides and resources for creating Reticulum networks over special or challenging mediums.

      @@ -476,28 +536,49 @@ plugin system for expandability.

      -
    + diff --git a/docs/manual/support.html b/docs/manual/support.html index 20910394..2eea7c1f 100644 --- a/docs/manual/support.html +++ b/docs/manual/support.html @@ -7,7 +7,7 @@ - Support Reticulum - Reticulum Network Stack 1.5.1 documentation + Support Reticulum - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
    • API Reference
    • @@ -285,8 +286,6 @@ Ko-Fi: https://ko-fi.com/markqvist
    -

    Are certain features in the development roadmap are important to you or your -organisation? Make them a reality quickly by sponsoring their implementation.

    Provide Feedback

    @@ -383,7 +382,7 @@ circumstances, so we rely on old-fashioned human feedback.

    - + diff --git a/docs/manual/understanding.html b/docs/manual/understanding.html index 1bfc726b..13e1188e 100644 --- a/docs/manual/understanding.html +++ b/docs/manual/understanding.html @@ -7,7 +7,7 @@ - Understanding Reticulum - Reticulum Network Stack 1.5.1 documentation + Understanding Reticulum - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
    • API Reference
    • @@ -1119,7 +1120,7 @@ those risks are acceptable to you.

    - + diff --git a/docs/manual/using.html b/docs/manual/using.html index 44817bfe..5d07627b 100644 --- a/docs/manual/using.html +++ b/docs/manual/using.html @@ -7,7 +7,7 @@ - Using Reticulum on Your System - Reticulum Network Stack 1.5.1 documentation + Using Reticulum on Your System - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
  • The rnstatus Utility

    -

    Using the rnstatus utility, you can view the status of configured Reticulum -interfaces, similar to the ifconfig program.

    +

    Using the rnstatus utility, you can view the status of and control configured Reticulum interfaces, similar to the ifconfig program.

    Usage Examples

    Run rnstatus:

    $ rnstatus
    @@ -571,6 +571,9 @@ options:
       -h, --help            show this help message and exit
       --config CONFIG       path to alternative Reticulum config directory
       --version             show program's version number and exit
    +  --attach name         Attach interface by name
    +  --detach name         Detach interface by name
    +  --reload name         Reload interface by name
       -a, --all             show all interfaces
       -A, --announce-stats  show announce stats
       -P, --pr-stats        show path request stats
    @@ -588,6 +591,8 @@ options:
       -w seconds            timeout before giving up on remote queries
       -d, --discovered      list discovered interfaces
       -D                    show details and config entries for discovered interfaces
    +  --show-stale          show stale discovery entries
    +  --show-unknown        show discovery entries without version info
       -m, --monitor         continuously monitor status
       -I, --monitor-interval seconds
                             refresh interval for monitor mode (default: 1)
    @@ -872,7 +877,7 @@ options:
     

    The rnx utility is a basic remote command execution program. It allows you to execute commands on remote systems over Reticulum, and to view returned command output. For a fully interactive remote shell solution, be sure to also take a look -at the rnsh program.

    +at the rnsh program.

    Usage Examples

    Run rnx on the listening system, specifying which identities are allowed to execute commands:

    $ rnx --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
    @@ -927,7 +932,7 @@ optional arguments:
     
    -

    The rnsh Utility

    +

    The rnsh Utility

    The rnsh utility provides a fully interactive remote shell over Reticulum. It allows you to establish encrypted, authenticated shell sessions on remote systems, complete with terminal emulation, pipe support, and window resizing.

    @@ -1311,6 +1316,7 @@ network_identity = ~/.reticulum/storage/identities/my_network
    • The autoconnect_interface_mode options specifies which mode discovered interfaces should be created with when auto-connecting.

    • The autoconnect_announces_to_internal option allows you to specify that auto-connected interfaces should propagate announces to internal mode interfaces, even if the auto-connected interface’s mode would normally not allow for this.

    • +
    • The autoconnect_unverified_implementations option will allow the interface discovery system to auto-connect to any announced interface, even those coming from unverified, experimental or potentially broken implementations. Be very careful with this option.

    @@ -1644,7 +1650,7 @@ systemctl --user enable rnsd.service - + diff --git a/docs/manual/whatis.html b/docs/manual/whatis.html index 3f077a6d..88d9d5a3 100644 --- a/docs/manual/whatis.html +++ b/docs/manual/whatis.html @@ -7,7 +7,7 @@ - What is Reticulum? - Reticulum Network Stack 1.5.1 documentation + What is Reticulum? - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
  • - + diff --git a/docs/manual/zen.html b/docs/manual/zen.html index a290a34b..66bceb26 100644 --- a/docs/manual/zen.html +++ b/docs/manual/zen.html @@ -7,7 +7,7 @@ - Zen of Reticulum - Reticulum Network Stack 1.5.1 documentation + Zen of Reticulum - Reticulum Network Stack 1.5.5 documentation @@ -180,7 +180,7 @@
    @@ -204,7 +204,7 @@
    - Reticulum Network Stack 1.5.1 documentation + Reticulum Network Stack 1.5.5 documentation @@ -227,6 +227,7 @@
  • Support Reticulum
  • Code Examples
  • Reticulum License
  • +
  • Brandolini’s Reference
    • API Reference
    • @@ -677,7 +678,7 @@ Imagine a messaging app. You write it once. It works on a laptop connected to fi
    - + diff --git a/docs/markdown/brandolinis.md b/docs/markdown/brandolinis.md new file mode 100644 index 00000000..0acd2d61 --- /dev/null +++ b/docs/markdown/brandolinis.md @@ -0,0 +1,1386 @@ +# Brandolini’s Reference + +> *A little learning is a dang’rous thing;* +> +> *Drink deep, or taste not the Pierian spring.* +> +> *There shallow draughts intoxicate the brain,* +> +> *And drinking largely sobers us again.* +> +> +> - Alexander Pope, 1711 +> + +This chapter serves as a helpful reference for developers, users and community members living in an Age of Bullshit Manufacture equivalent to the Cambrian Explosion. + +As we are surely only at the on-ramp of this trajectory, the chapter will continue to evolve, expand and be updated based on community feedback as events occur. + +## What The Reticulum License Is + +*To understand the legal reality relating to this section, see* [Void Grants](#brandolinis-void-grants). + +The [Reticulum License](license.md#license) is the license under which RNS, the Reticulum reference implementation, has been published since **April 15, 2025**, in versioning effective from **0.9.4** and every release since. In practical terms, it covers all of “modern Reticulum”: The current wire format, the cryptographic machinery as it exists today (including the AES-256-based link encryption, ratchets, et cetera), and all protocol additions that distinguish the modern implementation from the earliest pre-1.0.0 beta formats. If an implementation speaks today’s Reticulum protocol, it is, in all relevant respects, built on Reticulum-licensed work. + +The license is a permissive license. It grants the full range of rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, free of charge; subject to three conditions, which are reproduced here verbatim: + +> * The Software shall not be used in any kind of system which includes amongst its +> functions the ability to purposefully do harm to human beings. +> * The Software shall not be used, directly or indirectly, in the creation of an artificial +> intelligence, machine learning or language model training dataset, including but not +> limited to any use that contributes to the training or development of such a model or +> algorithm. +> * The above copyright notice and this permission notice shall be included in all copies or +> substantial portions of the Software. + +### Why This License Exists + +Reticulum was not moved to a custom license casually or quickly. It was licensed under the MIT license for the greater part of its existence, and that served well for a long time. The change came when it became clear that no existing license expressed what the project needed, and that the two most commonly proposed alternatives would either say the wrong thing or say nothing useful at all. Three factors had primary influence on the situation: + +**The harm problem** + +Reticulum is a tool that was built, deliberately and at great cost, to empower people; to make communication something you own rather than something you are temporarily granted. It has also been, at various times, exactly what certain kinds of organisations would like to use to control people. This is the duality of any powerful tool. A permissive license could not, and cannot, say anything about that; MIT is silent on the question of whether the software may be used to build systems designed to harm human beings. The Reticulum License is not silent. It does not pretend that a license can stop an individual madman; it does assert, however, plainly and in enforceable terms, that corporations and organisations integrated into the legal system cannot consume this software for harm and then claim they never knew. The line is drawn by the creators of the tool, not by an external authority, and it is drawn deliberately. This is covered in more depth in the discussion of the ethics of the tool in the *Zen of Reticulum*. + +**The appropriation problem** + +The second factor was the machine-learning appropriation of the open-source commons. By 2025 that was no longer hypothetical: The commons was already being systematically ingested by corporate training pipelines, and the code, words, and creativity of the people who built it were being converted into synthetic systems designed to replace them. The license responds to this with an explicit condition: The software shall not be used in the creation of an AI, machine-learning, or language-model training dataset, nor in any use that contributes to the training or development of such a model or algorithm. + +It is important to understand what this condition does and does not do, which matters for what follows in this chapter. **The AI-training condition is not the legal basis for protecting the code from machine copying**. That protection *already exists*, in the oldest and most well-tested form of copyright law, and it applies regardless of any license (see [Copyright & The Two Legal Layers](#brandolinis-copyright-and-layers)). + +The AI-training condition addresses something *additional*: the appropriation of the code *into the models themselves*; the ingestion of human-made work as raw material for a synthetic replacement, and the use of that ingestion to fabricate “prior work” minefields, patent-troll material, and a wall of slop meant to bury and devalue the actual ecosystem. That danger was foreseeable; the licensing decision was made with full awareness of it. The events of 2026 have since demonstrated, in public and in detail, that the concern was not theoretical. + +**The sustainability problem** + +Reticulum has been developed and maintained for over a decade by a single person, supported by a small group of contributors and network-building users, without corporate backing, without VC funding, through several serious attempts at commercialization and takeover from both the corporate and the ideological side. The license is part of what makes that sustainable, and possible at all. + +It ensures that the specific, painstaking labor of the reference implementation cannot be hijacked to undermine the intent of the project, while leaving the protocol itself, the mathematical rules of how Reticulum works, dedicated to the public domain, where it belongs to humanity and can never be owned. Anyone can implement the protocol, provided they themselves invest the *actual* work and effort. What the license protects is the work, and the intent embodied in it. + +### On Freedom + +The most persistent mischaracterisation of the Reticulum License is that it is “more restrictive” than the licenses it replaced or than the GPL family. This is backwards, and I’ll state the comparison plainly, because the confusion is the foundation of a great deal of deliberately manufactured controversy examined later in this chapter. + +The GPL and AGPL are constructed around a single, self-referential axiom: that “free” is *defined by the terms of the license itself*, and that any use falling outside those terms is not free. In practice, this means the GPL restricts the freedom of **everyone** - you may not write, distribute, link, or (in some cases) even communicate with GPL-covered software without the entire arrangement being pulled under the same terms, which the licensor then controls. The restriction applies to 100% of users, including the ones building purely constructive things. + +The Reticulum License restricts the freedom of almost nobody. Its restrictions apply only to: + +* Those who wish to use the software in systems that purposefully harm human beings, and +* Those who wish to ingest the software into AI training pipelines. + +That is a restriction on a vanishingly small fraction of would-be users - the 0.0000001% - and it is a restriction they can characterise however they like, forever. The bickering is itself a signal that the licensing decision hit exactly the right target. + +Everyone else retains the full breadth of use, modification, distribution, and sale, with none of the viral encumbrance of copyleft. + +Both licenses contain moral axioms. The difference is that the Reticulum License states its axioms out loud: + +* *Intentionally restricting the way that millions of people use and build upon a foundational + communications technology* - **The mechanism of copyleft** +* *Intentionally restricting a small number of organisations from using the technology to + violently harm human beings* - **The mechanism of the Reticulum License** + +Which of these is more free? The answer is not a matter of committee approval. It is a matter of what the word “free” means to the people *whose freedom is at stake*. The question of whether “open source” requires the blessing of a particular licensing orthodoxy is examined in [Open Source Means Open Source](#brandolinis-opensource). + +### The Prediction, And What Happened + +When the license change was made and publicly discussed in 2025, the following was said, in public, about the machine-learning threat: + +> A generative system could be trained on the Reticulum codebase, and for extremely low cost +> be set to work spewing out millions of source repositories for all kinds of ridiculous +> “Reticulum-based programs”. This is already happening. You can find several examples of this +> on GitHub already. … the point of this kind of trolling is to establish as wide a base for +> “prior work” as possible. By doing that, a patent troll or IP abuser can create an immense +> minefield for real developers. + +This was written when the phenomenon was just beginning. It was not a guess; it was a description of a mechanism already in motion, in the specific context of Reticulum, by people who had already begun to appear around the project. + +Less than a year and a half later, the prediction has now been demonstrated, in public, exhaustively and to the letter. There are now roughly a dozen machine-generated “Reticulum implementations” of the same shape: fluent, marketing-heavy, some without attribution, and - in several cases - actively harmful to the network. The [Prns case](#brandolinis-prns) is an example documented in this chapter. The pattern that produced it (and the people, mechanisms, and the recycling of falsehoods behind the *wider* phenomenon) is examined in [A Movement Of A Dozen](#brandolinis-movement-of-a-dozen). + +The license was written, in part, so that when this happened, the community would not be defenceless. + +### What This Means For Other Implementations + +Two simple things must be kept separate: + +1. **The protocol is public domain.** The mathematical rules of Reticulum - addresses, + signatures, routing, the wire format as an idea - belong to humanity. A *genuine* clean-room + implementation of the protocol, written by human beings who reasoned it out themselves, is + free and welcome, and owes nothing to the Reticulum License. Nothing in this chapter is an + argument against implementing the protocol. On the contrary: More good implementations, + honestly made, are good for the network. +2. **The implementation is licensed.** Copying the reference implementation - by machine or + by silk-screen press - and modifying and redistributing the result, is + exercising rights granted by the license, and is therefore subject to its conditions: The attribution + notice, the harm condition, the AI-training condition. A copy that does not follow those + conditions is **not** licensed, and it is not “open source in spirit”; it is an unauthorized + derivative work, and therefore a copyright violation. + +The distinction is the same one the license itself makes, and it must be held firmly: An implementation that *speaks* Reticulum is exercising the public domain protocol, **if** it was truly created independently. An implementation that was *generated from* RNS, reproduced by a copy process, is a derivative of licensed work. + +### Copyright & The Two Legal Layers + +The exact legal structure is frequently muddied in public discussion; and in several cases deliberately. + +**Layer A - Copyright (license-independent)** + +Copyright does not depend on any license. A primarily machine-generated copy of a copyrighted work - a copy not accompanied by demonstrable, substantial, new human creative input - is a derivative work over which the copier holds no copyright whatsoever, and the reproduction of which, without the original author’s permission, is an infringement of the original author’s copyright. This is standard, well-tested law, and it applies with equal force under the MIT license, the GPL, or any other license, because it is not about the license at all; it is about who created what. A process that copies the reference implementation into a machine, produces a transformed derivative, and then claims “Copyright, [name of the process operator]” - with no human able to account for the creative decisions in the result - **is not** asserting a valid copyright over the result. They are openly asserting the absence of one, and reproducing someone else’s work without authorisation. This is probably the cleanest cut copyright violation one could imagine. + +**Layer B - License Conditions (Reticulum License specific)** + +Where a copy *is* a licensed derivative, the conditions of the Reticulum License apply: The copyright notice and permission notice must be included in all copies and substantial portions; the harm condition must be honoured; the AI-training condition must be honoured. A derivative that follows none of these is unlicensed *a second way over*. + +The two layers are often intentionally confused in public discussion - the AI-training condition is waved around as if the entire question of machine copying rested on it, when in fact machine copying of copyrighted work is a copyright violation that would exist even under the most permissive license ever written. The purpose of keeping the layers separate is not rhetorical flourish; it is that Layer A is old, settled law, and does not rely on any novel legal theory, while Layer B is specific to this license. Both matter. Neither is a substitute for the other. + +Layer B is the required mechanism for closing the loophole where the work is *first* ingested during model training into the weights of a model itself, which would make any resulting violations almost impossible to detect and enforce. + +### The “Clean-Room” Delusion + +I regularly receive mail or LXMF messages from people who proudly and happily proclaim that they have created a “clean-room” implementation of one of the software systems I maintain; RNS, Sideband, LXMF or others. The declaration is delivered with the flat certainty of someone who believes they have found the legal lock-pick that settles everything at once: Their production is independent, uncontaminated, and therefore free of any obligation to the work they copied, its license, or its author. The proclamation usually concludes with a request for blessing, or at least acknowledgment. The proclamation is, usually, also generated by an LLM. + +This is a delusion, and I’ll cut through it surgically. The word they here invoke as magic is attempting to do a great deal of work it was never able to bear. + +**What a clean room actually was** + +The legal “clean room” is not folklore, incantation, witchcraft or a claim a person gets to make about their own output. It is a very specific, institutionalized procedure that grew out of the hardware and software litigations of the 1980s, and it existed for exactly one purpose: **Convincingly proving the absence of copying in a court of law**. + +The canonical case was Phoenix Technologies and its 1984 reimplementation of the IBM PC BIOS. IBM’s BIOS was copyrighted, which meant that the entire PC-compatible industry depended on being able to show that a compatible BIOS had been written independently, and not from IBM’s code. Phoenix’s answer was a physical and procedural firewall: + +* One team, the “dirty room”, read the original code and produced written *functional specifications*: descriptions of what the BIOS did, not how IBM’s code did it. +* A second team, the “clean room”, consisted of engineers who had *never seen the original code at all*, and they wrote the new BIOS from those specifications alone. + +This obsessively documented, legally attested separation was not a preference or a willy-nilly show for a kindergarten; it was the entire legal point, and it had to be *solid*. If even one clean-room engineer had *glanced* at IBM’s code, the clone would have been contaminated, and the defense would shatter. + +The other landmark case was *Computer Associates v. Altai* (1992), in which Altai had copied CA’s scheduler code into its own product, and (upon being caught) hired outside counsel to run a genuine clean-room procedure: A programmer with no exposure to the original was brought in to rewrite the infringing modules from functional specifications prepared by the team that had seen the code. The court credited the good-faith effort precisely because it was done, as the carefully documented record showed, to the letter of the procedure. + +Bear in mind what this procedure entailed in practice, because this is the part the modern claimants never seem to have even *heard* of: Physical separation of teams, legal counsel managing the process, signed and notarised declarations of non-exposure, controlled specification documents that described *behaviour* and never *code*, months of work, and testing against the specification - not against the original, which the implementers were forbidden to consult. + +The people on the clean-room side of the wall did not just *claim* they had not read the code. Their non-exposure was institutionally guaranteed, obsessively documented, and legally attestable through every fart and sneeze of the process, because the entire point was that a court - hostile, adversarial, and entitled to discovery - would believe it. + +*That* is the process. “Clean-room implementation” is the name of a *certified procedure for proving independent authorship*. It is not a mood, a marketing label, or a property a person gets to declare about their own work. + +**The moronic inversion** + +Now consider what is actually being described when someone says: *“I created a clean-room implementation of Reticulum by feeding the source code into a machine.”* + +That sentence is the opposite of a clean room. Feeding a copyrighted work into a machine so that it reproduces and transforms the work is **the definition of copying**, and a clean room is the one procedure whose entire purpose is the demonstrated *absence* of copying. This process cannot demonstrate the absence of copying, because the process is *composed of* copying. The cleanest possible room has been replaced by the dirtiest possible room, and the dirt has been installed as the base feature. What these claimants have actually performed is a photocopy with extra steps, and the extra steps, far from cleaning anything, are simply steps that forge a certificate they believe the output has earned. + +**Why the word is deployed** + +The word “clean-room” is deployed because it sounds like what the speaker wishes were true. It carries the accumulated legal prestige of the 1980s and 1990s - the BIOS clones, the Altai credit - and it sounds like a certificate already issued: *Independent, original, unencumbered*, the work of a person who owes nothing. The claimants want that halo without the procedure: No law firm, no physical separation, no written specifications, no signed declarations, no months of process - just a laptop, a loop, and the word “clean-room” typed into a README. The word must do the work of the process it replaces, and the delusional replacement is the entire point. + +**The irony runs deep** + +The Reticulum protocol is public domain. Any human being can implement it - from the mathematics, from the documentation, from their own reasoning - and owe nothing whatsoever to the license, to the reference implementation, or to me. + +An honestly written implementation needs no incantations, no legal theater, and no special vocabulary; it simply *is* what it claims. It’s plain for everyone to see. **It’s also plain for everyone to see when you’re faking it**. The people who reach for the word “clean-room” are, without exception, the people who need it to create a fantasy - and the people who need that are precisely the people who cannot have it. If what you wrote were genuinely independent work on the public-domain protocol, you would not need to call it anything. The word is not a seal of independence. In this context it is a confession of copying, filed by the copier, in the confident belief that it says the opposite. + +## Open Source Means Open Source + +An objection regarding the “open source status” of RNS appears occasionally in variations, but always reduces to the same syllogism: + +1. “Open source” means *licensed under one of the licenses approved by the Open Source + Initiative (or, in other variants, compatible with GPL orthodoxy)*. +2. The Reticulum License is not on that list. +3. Therefore Reticulum is not open source, and anything built on it is illegitimate. + +The entire argument rests on the first premise, and the first premise is false. + +Open source is not a certification conferred by a committee. It is a description of a fact: The source code is available, and the rights to use, copy, modify, merge, publish, distribute, sublicense, and sell it are granted to everyone, free of charge. + +The Reticulum License does all of those things. It is, in every substantive respect that concerns the person who wants to use, study, modify, or build upon the software, **an open license**. What it adds - and what disqualifies it in the eyes of the orthodoxy - is two conditions on *who may do what with the original work*, not on what the *user* is allowed to do with it. + +The definition being wielded against Reticulum is not even a young one. It is, in essence, the Debian Free Software Guidelines written in 1997, adopted by the OSI in 1998, and treated ever since by certain people as if it had descended from a mountain on tablets. It is an approach that is close to three decades old. Being old is not itself a flaw - but being old is also not a proof of correctness, and the suggestion that the meaning of a word like “open” was settled for all time by a committee in the 1990s, and may never be revisited, is not a position rooted in reason. It is rooted in institutional inertia dressed as principle, maintained by those whose ideologies it serves. + +### What The Argument Is Actually Doing + +I would like to go into some detail about the rhetorical mechanism, because it is roughly the same mechanism that powers the rest of the campaign described later in this chapter. + +The orthodoxy’s argument is self-referential: *“open source means what we say it means, because we are the ones who define it.”* When the Reticulum License is measured against that definition and found wanting, the conclusion is presented as a property of Reticulum - when in fact it is *a property of the definition*. The definition is treated as neutral and authoritative - as some base fact of raw cosmology - and the license is treated as deviant. But the definition is no more neutral than the license is. It encodes a moral position, and that moral position is exactly the one that this project declines to take. + +Consider what the orthodoxy’s definition requires, in the case at hand. The OSI-based definition contains, in its ancestry, the Debian Free Software Guideline of “No discrimination against fields of endeavor”: The software must not restrict who may use it or for what purpose. Taken to its logical end, this means that open source, properly “certified”, must be equally available to those who build hospitals and those who build weapons, those who connect people and those who control them, those who create and those who ingest and replace. + +The orthodoxy presents this as neutrality. It is not neutrality; it is a moral position - one that says, in effect, that *harming human beings is a field of endeavor like any other, and software must not discriminate against it*. + +The Reticulum License takes a different position, and it has the honesty to state it in the license text: this software is for life, not for death; it is for people, not for the systems that would replace them. That is not a restriction on openness, nor on freedom. It is a restriction on *who may consume the work*, and it is a restriction the orthodoxy’s definition cannot express - which is why the orthodoxy must always attack the license as “not open source” rather than engage with what it actually does. + +### Who Is Restricted By Which License? + +The arithmetic is simple, so let’s do it out loud, because the orthodoxy’s framing inverts it every time. + +The GPL family imposes its conditions on **everyone**: You may not distribute, link, or - in the AGPL case - even *communicate with* GPL-covered software without your own work being pulled under the same terms. “Free” in this system is defined (self-referentially) *by the license’s own terms*; everything outside those terms is, by definition, unfree. The restriction applies to 100% of users. It applies to the hospital, the mesh community, the school, and the hobbyist with the same force it applies to anyone else. That is not freedom for everyone; it is a *specific moral architecture applied to everyone*, presented *as if it were the absence of one*. + +The Reticulum License imposes its conditions on a fraction of would-be users so small as to be practically unmeasurable: + +* Those whose intended use is to build systems that purposefully harm human beings, and +* Those whose intended use is to ingest the work into AI training pipelines. + +That is the entire list. Everyone else - the overwhelming majority, the community, the developers, the users, the downstream projects - receives the full, unrestricted rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, with none of the viral encumbrance of copyleft. + +So when the claim is made that the Reticulum License “is more restrictive” than the GPL, the claim is not merely wrong; it is the exact inverse of the truth. The GPL restricts the freedom of everyone, in the name of a specific ideology. + +The Reticulum License restricts the freedom of the harm-doer and the appropriator, and leaves everyone else free. The two approaches do not differ in whether they contain moral axioms - **all licenses do**. They differ in whether the axioms are stated openly, and in *whose* freedom they restrict. + +### The Consequences Of The “Not Open Source” Claim + +This would be a footnote debate if the mischaracterisation had no practical consequences. It has very large ones, and therefore this section exists. + +The claim that “Reticulum is not open source” is the foundation of the takeover narrative it so often accompanies. The sequence is always the same: + +* First, declare the reference implementation illegitimate (“not really open source”, “owned by one man”, “not a real community project”) +* Second, conclude that it is therefore acceptable - even necessary - to replace it. +* Third, present the replacement, which is (conveniently) often the speaker’s own machine-generated clone, as the legitimate heir. + +This is not speculation about motives; it is the documented structure of the campaign examined in [A Movement Of A Dozen](#brandolinis-movement-of-a-dozen). + +The “not open source” claim is the legal-ideological battering ram of that campaign. It is recycled, in article after article, in forum after forum, because it works on people who assume that a committee’s definition is the same thing as the truth. + +It is also worth stating the other obvious fact: None of these critics have ever shown that the Reticulum License restricts *them*. They do not build weapons. They are not training models on the codebase. They are free, in every practical sense, to use Reticulum exactly as they would under MIT or GPL. Their objection is not to a restriction on themselves; it is to the *mere existence* of a license that states a moral position they disagree with, or which they can use as leverage for a different goal entirely, and to the institutional fact that it does so outside *their* system of approval and control. The complaint is not that the license makes them unfree. The complaint is that the license is *free of them*. + +### The Distribution Argument + +A recurring companion claim is that RNS is not properly “distributed”, usually deployed as “it’s not packaged as a .deb” or “it’s not on package manager X”, with the implication that it is somehow unavailable or inaccessible, or hard to install on a given system. + +This is simply false, and it has been false for years. The reference implementation is available on practically every platform and architecture with a single command (`pip install rns`). It is packaged in the Arch User Repository, in NixOS, and in a range of other distribution channels, community-maintained and official. It can be installed, updated, and kept current *over Reticulum itself* - the network transports its own software updates. It is used on more than a hundred thousand devices worldwide, is embedded in over a hundred other packages and applications, and carries terabytes of traffic every day. + +The claim that Reticulum needs a `.deb` to be “really distributed” mistakes the mechanism for the goal. The goal is that people can obtain and update the software easily, everywhere, **on their own terms**, and distribute it themselves, both offline, online and over Reticulum with full cryptographic verification of the install packages, without any central infrastructure. + +That goal is met to an excellence that few software packages can speak of, and met in a way that does not pin the project’s release cadence to the review cycles of distribution maintainers, which is an achievement, not a bug. + +A project like RNS that updates continuously, sometimes daily, and has a track-record of shipping security updates mere hours after issues are discovered, would be crippled by packaging that makes every change wait months for approval. The distribution complaint is a strawman generated for the occasion. It has been answered, in public, many times; it is repeated anyway, because the people repeating it are not counting on facts - they are counting on the reader never having heard the answer. + +### On The Institutions, In Fairness + +None of the above is hostility toward the Open Source Initiative or the Free Software Foundation as institutions, nor toward the individuals who have dedicated decades of work to them. Their contribution to the world of software is **enormous**, and this document does not dispute it. What is disputed is a specific claim of authority: That “open source” is a term whose meaning is reserved to a committee’s approval, and that a license which does not submit itself to that approval is therefore not open. + +That claim of authority is not in Reticulum’s interest, and it is not in the interest of the people the movement claims to serve. The current legal and technological landscape - the machine-appropriation of the commons, the weaponisation of “prior work” generation, the erosion of human agency by synthetic systems - was not anticipated by the DFSG of 1997, and the institutions have not, as of this writing, produced *any* meaningful answer to it. The choice, as it was put at the time of the license change, is whether developers should sit back and wait for a solution from a committee that “may or may not ever materialize, before the entire foundation we stand on has been eaten away”. + +**Reticulum’s answer was to act**. If we had waited, it would have been too late. + +If an OSI-approved license existed that expressed the same constraints - and did not impose the far more severe restrictions of copyleft - the project would have used it. None such exists. That is not Reticulum’s failure. It is the measure of what the definition is missing. + +### What “Open” Means Positively + +For anyone who wants the positive statement rather than the rebuttal, Open Source, in this project’s understanding, means: + +* The source code is available, to everyone, without charge +* Everyone may use, copy, modify, merge, publish, distribute, sublicense, and sell the + software +* No one is discriminated against as a person - developer, user, community, or project +* The protocol itself is dedicated to the public domain, where no one can own it +* And the single, plainly stated condition of the license is that the work shall not be + consumed to harm human beings, or ingested to replace the humans who made it + +If that is not “open” by a definition written in the 1990s, then the definition is the thing +that has failed - not the software, and not the people who use it. + +**Open source means open source**. It was true before the committees existed to certify it, and it will remain true after they are gone. + +## Assistance Versus Machine-Substitution + +### False Dichotomy + +The public discussion around machine learning and software development has been derailed, by the loudest voices on both sides, into a farcical fight between “AI enthusiasts” and “AI haters”. + +> **Both positions are absolute caricatures.** + +> **The fight is beside the point in the ways that matters most.** + +It is not an accident, but a very conscious choice that the initial analysis of the Prns case examined herein, and this very chapter, were themself produced with the assistance of a machine-learning based generative system. + +Specifically, it was generated using `lc` managing a `Q8_K_XL` quant of `DeepSeek v4 Flash` running in the `llama.cpp` inference engine. The main context base used to stabilize, ground and inform the generative environment consisted of approximately 100,000 tokens of text material that I personally thought out and wrote (by hand), then archived and organized, over the last eight years. + +If you know my writing, and have a hard time discerning where this chapter is me directly, typing manually, and where it is the machine output, it is because of two things: Almost every line in this chapter was either directly edited by my hands on the keyboard or typed by me, and the text corpus that informed the process *is* genuinely me - my thoughts, written by me, over a period of years. + +The chapter was produced this way *deliberately and openly*, under a software framework I designed and wrote, with the human directing the inquiry points, flow of investigation, structure of the outputs, contents of every section, making the editorial decisions, reviewing the conclusions, painstakingly adjusting every line, and taking responsibility for the final claims presented, with the goal of reaching a higher level of synthesis and symbolic density than I could have achieved without that assistance. + +The tool was *used as tool*, both to structure and produce a complex chapter, and to inspect a repository so preposterous in size, commit velocity and nonsensical wording that it barred any purely human inquiry. + +As such, the position is hereby, by personal example and demonstration, stated clearly: + +* **Technological assistance is not the problem** + +* **It was never the problem** + +* **It is the opposite of the problem** + +The problems are *substitution* and *usurpation*: The perverse process in which the machine becomes the author of choices, and the human becomes the facade of software, while expecting “reciprocity” or recognition for deeds they never performed. + +### The Line + +The exact distinction can be reduced neither to how many lines of code a machine produced, nor who pressed the keys. The final distinction has to rest on **who, or what, the real agent of the work is**. + +* **Assistance** is when the human retains the full seat of agency: The human decides what to build, judges + what is correct, rejects what is wrong, understands what is shipped, and can answer for every single line of it. + The machine writes, suggests, drafts, accelerates *meaningfully* and within reason - but every choice that survives into the + final work is a choice the human made *consciously*, and understood - or grew to understand - the consequences of. + +* **Substitution** is when the machine *becomes* the agency: the machine decides what to build, + decides what is correct, iterates on its own errors, generates at a scale and speed no single + human can follow - and the human’s role is reduced to providing the name, the account, the + signature, and the marketing launch. + +> The Line can be stated as a single test, and this is the same test that has always separated authorship from couriership: **Can the person whose name is on the work answer for it fully?** Not “can they describe what it does” - can they account for why it is the way it is, line by line and decision by decision, and the history of how it came to be that way, under questioning, without machine assistance, including by people who know more than they do? + +If they cannot, they did not author the work. They wore it, or in more severe cases, they stole it. And a courier who claims authorship is not a writer; they are a fraud. + +### What assistance looks like + +Assisted work is recognisable, and recognisability is itself part of its value. It has the following observable properties: + +1. **The human can explain it.** Under examination, the author can say why this choice was + made, what was rejected, and what they verified. The ability to explain is not a luxury; + it is the very demonstration of authorship. On a large project with many contributors this is partial in + practice - no one can explain every line of a large codebase - but the *full capacity* must + exist between the authors and the *habit* must be visible. +2. **The human can, and does, reject machine output.** An author who has never rejected the machine’s output is not + an author, but an open drain. Rejection is not a stylistic flourish; it is the + mechanism by which any work attains Quality. A record of decisions, including reversals and rejections, + is a sign of agency. A record without rejection is a record of assent-by-default. +3. **The human’s judgment is directional.** The work contains the human’s actual choices; + things the machine would not have decided on its own, which the human can defend on their + merits. This directionality has many names in engineering: Design, architecture, taste, + judgment. Where it is absent, the work has the uniform, self-consistent texture of + something that was never doubted, and doubt is exactly what anything important requires. +4. **Provenance is not concealed.** Disclosure of how the work was made is not a legal + requirement in every jurisdiction; it is not even always a practical requirement. But it + is a *statement* that matters. A project that discloses its process - + including its use of machines - is telling the truth about the relationship between the + human and the work, and that is a property users *are* entitled to know. Concealment of + provenance is not a stylistic choice; it is deception, made by someone who knows what the + record would otherwise show. +5. **The human stands behind the failures.** When assisted work fails, the human can say: Yes, I + chose this, under these assumptions, here is why, here is what I got wrong, here is the fix. + That sentence is the entire contract between an author and the people who depend on their work. + A human who cannot say it - because the choices were never theirs - *has nothing to offer anyone*, and + is by definition entirely replaceable; anyone else could have pressed the same button. + +### What substitution looks like + +Substitution is equally recognisable, once the pattern is known: + +1. **Scope that no human could have authored.** Output that + structurally cannot have been the product of human authorship, review, and judgment, for + example when the volume exceeds any reasonable human capacity within the span of the project’s life. + When the review capacity and the output volume are incommensurable, the output was not + reviewed. It was generated, then forgotten, and the record was signed blindly. +2. **Uniform generation.** The work carries no trace of a human’s changing mind. No style + drift, no contested decisions, no “we tried X and it was wrong, so we did Y”. That is, *no + signs of actual development, growth and learning*. Instead, endless, self-referential + refactoring, renamed abstractions, and the same fluent register in every commit, + every document, every reply. A human’s history shows the wear of judgment. + Pure generation shows the superficial polish of its absence. +3. **Discovery by recursive regeneration.** When errors are found, they are found by the machine’s own + subsequent runs, not by human scrutiny - and the findings are recorded as planned + “reviews” and “alignments” rather than as the corrections they are. This is the tell: A + machine editing its own previous output, while the edit is recorded as if it were a + scheduled milestone. That’s not review. That’s a continuous generation loop revising itself, + with the attempt of an illusion-preserving voice-over. +4. **Laundered provenance.** Theatrical concealment machinery: Commit hooks that refuse + attribution of machine generation, contribution policies that declare machine output + “yours”, processes that scrub personal traces from the history, fake identities in the + contributor list. All of these have one function: To make the record say what the “author” + *wished* had happened, rather than what happened. A project that builds such machinery is + not making a record of its work; it is using automated software to manufacture one. +5. **Authorship by assignment.** The human’s name is on the work, but the human cannot + answer for it - because the human did not choose any of it, and knows it. The name is not a + signature of authorship; it is a *fraudulent claim of ownership* over something the claimant did not + make and cannot explain. In every field that has ever dealt with such claims - art, + literature, invention, journalism - *this has a name*. That **forgery** is now cheap in software + makes it no more forgivable. + +### Infrastructure Matters + +For a hobby project, the distinction between assistance and substitution is a personal matter. For infrastructure - code that other people’s communications, safety, and freedom run on - it is a matter of life and safety, and any statement about this must be entirely unapologetic. + +Infrastructure has one property that distinguishes it from almost all other software: While most of the people who depend on it cannot verify it themselves, **it must be verifiable, auditable and open to human inspection**, and be engineered in such a way that this is as frictionless and straight-forward as possible. + +The reference implementation of Reticulum was designed this way, and continues to make that goal a primary one. While it *is* a complex piece of software, with an intricate array of interlocking and moving parts, the core parts of RNS, the entire Reticulum protocol implementation, the transport logic, the cryptographic primitive interfaces, **is less than 15,000 lines of code**. That line count even includes the rather extensive comments, incredibly detailed logging facilities and other choices that makes the code easy to read and understand for humans, and easy to operate, verify and debug. It took real dedication, and *a lot* of hard work to achieve that. + +Exactly because not *everyone* can do this, it is a fundamental necessity for infrastructure software that it is designed and authored so that *as many as possible can*, and that the *chain of accountability* - who made it, who reviewed it, who answers for it - is held intact at every link. That chain is not decoration. It is the entire mechanism by which normal users decide to trust a system they cannot fully verify. The transparent foundations and the chain combined *is* the verification for most users. + +Substitution breaks the chain both at the foundations, and at its load-bearing link: The human at the top can no longer answer, because they were never the maker. Unfortunately, the chain does not always fail visibly; often it fails silently, at the exact moment a question goes deep, or when routing fails subtly at a critical moment. + +For the user, the result is not a project with a normal and humanly flawed author - it is a project *with no author at all*; a signature with no substance behind it, a name that cannot be held to account, and a body of work that nobody on earth can (or wants to) explain, defend, or fix in a crisis. + +### The Fluency Trap + +It is worth understanding, briefly, why substitution is so attractive and so dangerous at once. Machine-generated output is fluent. It is confident, well-structured, and terminologically *self-consistent*. At the surface, and from the perspective of someone outside a given craft, it is indistinguishable from the output of a knowledgeable human. Fluency of this kind can be a useful property: It makes assisted work fast. But fluency is *not* understanding. It is the *minimal conformal surface* of understanding. + +The danger is that the surface is exclusively where the substituter invests; for the simple reason that the surface is where most of the desired audience looks, and what yields attention to the project. + +A human who can tell the difference uses the tool well. A human who cannot is being deceived through means they cannot detect from inside, namely through their own inability to account for the limits imposed by what they do not know. + +This is why the most important quality for anyone working with systems like Reticulum is not speed, and not vocabulary, but the oldest engineering virtue there is: The honest, uncomfortable, terrorizing knowledge of **what you do not know**. The substitute *never* has it. The substitute’s operator, *if* they ever had it, loses it precisely the moment they accept the fantasy of the substitution process. + +The tool is not the hazard, plain old human nature is. The tool is a mirror, and mirrors - as has been observed for rather longer than software has existed - show the truth only to those willing and yearning to see their own shortcomings. + +### Disclosed Assistance Or Laundered Generation + +The contrast at the centre of this entire discussion can be made clearer with two examples, both of which are publicly accessible, both produced in the same year, by people using the same class of tools. + +The first is this chapter. It was produced with machine assistance, openly: the structure was directed by the human, the material was assembled with the tool’s help, every conclusion, every line, every slight nuance of meaning and semantics was examined, edited, and accepted or rejected by the human, and the process described publicly - including the precise characteristics of the technological assistance framework used. The human can answer for every claim in these documents, because the human made the decisions the claims rest on. + +The second is the project examined in [the Prns case](#brandolinis-prns). It was produced by a machine, at a volume no human could review, and the authorship record was engineered to erase the machine’s role: A commit hook that refuses attribution of machine generation, a contribution policy declaring machine output the human’s own, a fictitious contributor identity, 637,000 lines of unreviewed code. The human cannot answer for the code, because the choices were never made by a human - only the conformal surface of the presentation was. + +The same tool class. The same technology. Two diametrically opposed relationships to truth and responsibility. **The difference is not the tool**. The difference is the presence or absence of the human as the agent of the work - and the honesty or concealment with which that relationship is recorded. + +Assistance leaves the human as the agent and the commons as the source from which the human works and can grow. Substitution removes the human from the loop and converts the commons into fuel for the thing that seeks to replace them, or usurp their work for the profit of the few, human atrophying in the process. + +### The License In This Context + +The Reticulum License, examined in [What The Reticulum License Is](#brandolinis-what-the-license-is), draws the same line, at the level of the law. Its AI condition does not forbid the use of machine-learning technology to *assist* development - no reading of the license could support that, and no one associated with this project has ever claimed so. What the condition forbids is the *appropriation of the work into the machine itself*: The ingestion of the commons as raw material for synthetic replacement, and the concealed fabrication of “prior work” that would bury the real thing. + +As also noted in [Copyright & The Two Legal Layers](#brandolinis-copyright-and-layers), plain old copyright law already protects against the case where a process copies the reference implementation into a machine, produces a transformed derivative, and then claims “Copyright, [name of the process operator]”, with no human able to account for the creative decisions in the result. That is simple, petty theft, as it always has been. + +### The General Principle + +In these regards, the position of this project can be codensed to something relatively concise: + +* Machine assistance in human learning, development, and creation is accepted and useful. + It is not a shameful secret; but it *is* a tool that needs knowledge, training, understanding, + and great care to use. It should not make anything easier or more fun, it should make the + results better, more carefully considered, and arrive at *higher levels of synthesis*, not + produce endless streams of code churn. +* The line is crossed when the human stops being the agent of the work. When *any* output is + accepted that the human cannot explain, produced at a scale the human cannot review, or filed under a record + where the human has arranged to conceal the fact. +* The line is crossed, when a human claims authorship of work they cannot + answer for or has usurped. Credit follows the ability to answer. It has always worked that way, and + machines do not change the rule - they only make it cheaper and more tempting to break. +* The people who depend on infrastructure have the right to know which side of the line + the code they run was made on. That knowledge is the only verification most of + them will ever be able to perform. + +Use assistance, by all means, *and learn*, but don’t substitute. And never sign what you cannot answer for. + +Somewhere, within the general shape of the conceptual framework outlined in this section, or realistically, a more refined variant of it, I do believe there is the *potential* of the *beginning* of a constructive outcome to the immense challenge we are faced with as a species in regards to these problems. + +At the same time, I reserve my right to revert that position to Butlerian Jihad without prior notice. We are on a knife’s edge, and you know it just as well as I do. + +## Void Grants: Legal Foundations of Machine-Generated Code + +A grant of rights is only as real as the rights behind it. A license conveys what its issuer holds, and nothing more. A derivative may be distributed only under whatever license covers what it took. And over a work that a machine originated, no human holds anything at all. + +Each of these statements is a matter of settled statute and case law, and this section sets out the authorities. The conclusions they support are: + +1. A software implementation generated from a licensed work by a machine, published under its operator’s claimed copyright and license, **conveys rights the operator never possessed**. +2. **Its grant is void**. The projects, products, and promises built upon such grants stand on nothing. A field of void grants is a minefield for everyone who crosses it. + +This section is a general examination of copyright law as it applies to machine-generated code. It is not legal advice. + +### I. The Foundational Statute: Translation Is Copying + +The starting point is the statutory definition of the class of works at issue. Title 17, United States Code, section 101 provides the definition of a derivative work: + +> A “derivative work” is a work based upon one or more preexisting works, such as a *translation*, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or *any other form in which a work may be recast, transformed, or adapted*. + +Section 101 further provides that *“the terms ‘including’ and ‘such as’ are illustrative and not limitative”*. As such, the list is a list of *examples*, and the very first example is translation. The definition also reaches, in its own words, *“any other form in which a work may be recast, transformed, or adapted”*. + +The exclusive right at issue is defined in section 106: + +> Subject to sections 107 through 122, the owner of copyright under this title has the exclusive rights to do and to authorize any of the following: +> (1) to reproduce the copyrighted work in copies or phonorecords; +> (2) to prepare derivative works based upon the copyrighted work; +> (3) to distribute copies or phonorecords of the copyrighted work to the public by sale or other transfer of ownership, or by rental, lease, or lending; + +Violation of any of these rights is infringement. 17 U.S.C. § 501(a). + +Taken together, the provisions yield a construction that is difficult to improve upon and impossible to escape: + +1. **A port is a translation.** A work that takes a program written in one language and from it produces a program written in another language, implementing the same behavior, is a translation of the original - whatever mechanism performed it, and however the surface presentation differs. +2. **A translation is a derivative work.** Section 101 says so, explicitly. +3. **Preparing a derivative work is the copyright owner’s exclusive right.** Section 106(2) says so explicitly. A derivative work prepared without authorization, or outside the scope of any authorization, infringes that right. + +The common objection - “the code is in a different language, so it is completely different” - is not a legal argument; it is the definition of what the statute already classifies. + +Translation *is the paradigm* of derivative authorship, not an exception to it. If translating a work without permission was a defense, the derivative-work right would be meaningless; every infringing adaptation would simply need to be “different enough” to count as a translation of its source. + +Nor does the identity of the translator change the analysis. The statute asks whether the work is “based upon” a preexisting work. It does not ask who or what performed the translation. A machine that ingests a licensed work and reproduces a translated transformation of it has performed mechanical translation; the output is a derivative of the ingested work, and the law governing derivative works applies to it exactly as it applies to a translation made by hand. + +### II. Ideas Are Free, Expressions Protected + +The second foundation is the distinction between what a work *is* - its ideas, its processes, its systems - and the *expression* in which those ideas are embodied. The distinction is codified in section 102(b): + +> In no case does copyright protection for an original work of authorship extend to any idea, procedure, process, system, method of operation, concept, principle, or discovery, regardless of the form in which it is described, explained, illustrated, or embodied in such work. + +The principle is older than the statute, and its application to software is settled. An author may own the particular code in which a method is expressed; the method itself, the process, the algorithm, belongs to no one - because *“the sine qua non of copyright is originality”* (*Feist Publications, Inc. v. Rural Telephone Service Co.*, 499 U.S. 340, 345. 1991). And ideas are not original to anyone in particular, *Baker v. Selden*, 101 U.S. 99 (1879), established the line: Copyright in a book describing a system does not prevent others from practicing the system. + +Applied to a communications protocol, the structure is clean: + +--- + +**An implementation of a public-domain protocol, honestly reasoned and written by humans, is welcome and unencumbered, and owes nothing to any license. An implementation generated from a licensed implementation is a derivative of licensed work, subject to its conditions and to the ordinary copyright of its source.** + +--- + +The public-domain status of the protocol’s ideas changes nothing about the copyright in an implementation’s expression. A person who copies an implementation - by machine or by hand - cannot defend the copying by pointing to the protocol, because the protocol covers the ideas, not the symbols in which someone expressed them. + +A further misconception can be dismissed here; the recently popularized “clean-room” claim about the absence of copying. A [clean-room](#brandolinis-cleanroom-delusion) is a not a magic label achievable by LLM, but a specific, institutionalized procedure for proving to a court that copying did not occur: Physically separated teams, written functional specifications, attestable non-exposure, and no access to the original by the implementers (*Altai*, 982 F.2d at 709–11). + + *“I created a clean-room implementation by feeding the original source code into a machine”* attempts to *claim* the certified, legally established procedure for proving the absence of copying by describing, in the same breath, a process **composed entirely of copying**. The word is deployed because the procedure it names is what the claimant would *need to have happened*. + +### III. Machine Output Has No Author + +The third foundation is the human authorship requirement. It is settled at both levels of the federal courts and in the Copyright Office’s administering practice. + +In *Thaler v. Perlmutter*, the district court held that *“copyright law protects only works of human creation,”* and that *“human authorship is a bedrock requirement of copyright”* (687 F. Supp. 3d 140, 146, D.D.C. 2023). On appeal, the United States Court of Appeals for the District of Columbia Circuit affirmed, holding that the Copyright Act *“requires all eligible works to be authored in the first instance by a human being”* (No. 23-5233, D.C. Cir. Mar. 18, 2025). + +The requirement traces to the ordinary meaning of the statutory term. In *Burrow-Giles Lithographic Co. v. Sarony*, the Supreme Court defined an “author” as *“he to whom anything owes its origin; originator; maker; one who completes a work of science or literature”* (111 U.S. 53, 57–58, 1884), and more recently described the author as *“the person who translates an idea into a fixed, tangible expression entitled to copyright protection”* (*Community for Creative Non-Violence v. Reid*, 490 U.S. 730, 737, 1989). + +--- + +**A machine does not owe expression its origin; it reproduces it. No court has recognized copyright in material created by non-humans, and the courts that have addressed the question have rejected it. If you create by machine generation, you do not own the output.** + +--- + +The Copyright Office’s registration guidance applies the requirement to generative systems in terms that are directly on point. The Office asks: + +> whether the “work” is basically one of human authorship, with the computer [or other device] merely being an assisting instrument, or whether the traditional elements of authorship in the work (literary, artistic, or musical expression or elements of selection, arrangement, etc.) were actually conceived and executed not by man but by a machine. +* *Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence*, 88 Fed. Reg. 16190, 16192 (Mar. 16, 2023) + +And it states the consequence: *“If a work’s traditional elements of authorship were produced by a machine, the work lacks human authorship and the Office will not register it”* (*Id.*). + +On the role of prompts, the Office is equally explicit: when a system receives a prompt and produces a work in response, *“these prompts function more like instructions to a commissioned artist - they identify what the prompter wishes to have depicted, but the machine determines how those instructions are implemented in its output”* (*Id.*). + +The agency applied this standard and excluded machine-originated material from registration in the leading administrative case. In *Zarya of the Dawn* (Cancellation Decision, Feb. 21, 2023, Registration No. VAu001480196), the Office cancelled registration of images generated by the Midjourney service, holding that *“it was Midjourney-not [the author]-that originated the ‘traditional elements of authorship’ in the images”*, while preserving protection for the human-authored text and the human selection and arrangement of the work. + +The Copyright Office’s 2025 report on AI copyrightability reaches the same conclusion: + +> Based on the functioning of current generally available technology, prompts do not alone provide sufficient control. +* U.S. Copyright Office, *Copyright and Artificial Intelligence, Part 2: Copyrightability*, at iii (Jan. 29, 2025) + +The report’s analysis is explicit: *“The Office concludes that, given current generally available technology, prompts alone do not provide sufficient human control to make users of an AI system the authors of the output. Prompts essentially function as instructions that convey unprotectible ideas”* (*Id.* at 18). + +Its guiding distinction is stated plainly: *“The use of AI tools to assist rather than stand in for human creativity does not affect the availability of copyright protection for the output”* while *“Copyright does not extend to purely AI-generated material, or material where there is insufficient human control over the expressive elements”* (*Id.* at iii). + +The boundary is therefore not “AI or no AI”. It is *assistance or substitution*: Whether a human exercised sufficient creative control over the expressive elements and can answer for them, or whether the machine originated them and the human merely supplied instructions and a signature. That is a question of fact in each case, determined from the record of how the work was made. + +Two facts follow, and stated together, they form the base legal reality: + +1. **A work whose expressive elements were originated by a machine contains no valid new copyright: It has no human author. To the extent that the same work reproduces a preexisting copyrighted work without explicit license, it is at the same time an unauthorized derivative. It is unowned for anything new it contains, and unlicensed for everything taken.** +2. **Its operator therefore holds no copyright in it and no grant over it - and a person who holds neither copyright nor grant can convey neither.** + +The first fact makes the work **unownable** by its operator. The second makes it infringing against its source. Neither replaces the other: + +* The absence of copyright in machine output does not make the output free for anyone to take; it makes it unowned. +* This is a different thing entirely, especially when what it contains is someone else’s expression. + +### IV. License Conditions Bound the Grant + +The fourth foundation governs what a license *is*. A copyright owner may grant permission to use the work on conditions. The conditions define the scope of the permission. Use outside the scope is use that was never authorized. + +In *Jacobsen v. Katzer*, 535 F.3d 1373 (Fed. Cir. 2008), the Federal Circuit held that the conditions of an open-source license are *conditions of the copyright license itself*, not mere contractual promises, and that a licensee operating outside them is an infringer: + +> Copyright holders who engage in open source licensing have the right to control the modification and distribution of copyrighted material. + +> The choice to exact consideration in the form of compliance with the open source requirements of disclosure and explanation of changes, rather than as a dollar-denominated fee, is entitled to no less legal recognition. + +> It is outside the scope of the [license] to modify and distribute the copyrighted materials without copyright notices and a tracking of modifications from the original computer files. +* *Id.* at 1381–82 + +The doctrinal mechanism is settled: *“A copyright owner who grants a nonexclusive license to use his copyrighted material waives his right to sue the licensee for copyright infringement”* within the scope of the license. If, however *“the licensee acts outside the scope, the licensor can bring an action for copyright infringement”*: An act outside the granted scope **is infringement** (*Sun Microsystems, Inc. v. Microsoft Corp.*, 188 F.3d 1115, 1121, 9th Cir. 1999; *Graham v. James*, 144 F.3d 229, 236, 2d Cir. 1998; *S.O.S., Inc. v. Payday, Inc.*, 886 F.2d 1081, 1087, 9th Cir. 1989). + +Whether a given license term is a condition of the grant or a mere covenant is determined from the license’s own language; conditions that limit what may be copied, modified, and distributed - the attribution terms, the notice terms, the modification-tracking terms, the field-of-use terms - are the boundaries of the copyright grant (*MDY Industries, LLC v. Blizzard Entertainment, Inc.*, 629 F.3d 928, 940, 9th Cir. 2010). + +Three consequences follow for the analysis at hand. They are not hypothetical. + +**First, the conditions are measured at the moment of copying** + +A work is licensed under whatever conditions applied when the reproduction, adaptation, and distribution occurred. There is **no** period in which copying a licensed work is “free” because the copy was made by a machine; the machine is the *licensee’s tool*, and the licensee is bound by the conditions regardless. A derivative generated without satisfying the conditions - without the attribution, without authorization for the manner of use - was never within the scope of the license, from the first instant of its existence. + +**Second, breach does not restore rights that never attached** + +The district court in *Artifex Software, Inc. v. Hancom, Inc.*, No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017), analyzing the GPL’s termination provisions, observed that *“the language of the GPL suggests that [the licensee’s] obligations persisted beyond termination of its rights to propagate software using Ghostscript,”* because the source-code obligation recurs each time a covered work is conveyed. The same structure operates a fortiori where a derivative was produced *outside* the license entirely: No grant ever attached, and no subsequent event creates one. + +**Third, the settled conditions are the enforceable core** + +The attribution and notice conditions rest on the settled doctrine above. Novel conditions (restrictions on field of use, restrictions on how the work may be consumed) are enforceable as conditions of the grant when clearly drafted, but their enforcement history is thinner. The argument that a derivative is unlicensed does *not* depend on the novel conditions being vindicated; it needs **only** the settled ones, and the ordinary law of derivative works, to stand. + +### V. The Void Grant + +The preceding sections assemble into a single structure. Let us apply it to an example situation: + +* A project presented as an independent implementation of a protocol; “ground-up”, “from scratch” or “clean-room” work. +* The actual history shows continuous, machine-mediated ingestion of a licensed reference implementation. +* The output is generated at a scale no human could produce or review, with the provenance of the process obscured. + +**Step One: The derivative** + +The project’s output is a translation of the licensed implementation: A derivative work, produced by a copy process. 17 U.S.C. §§ 101, 106(2). Preparing it without authorization infringed from the first moment of its existence. *Id.* § 501(a). + +**Step Two: The license** + +The derivative was produced outside the conditions of the license; without the notices, without the attribution. The license never attached (*Jacobsen*, 535 F.3d at 1381–82). + +**Step Three: Authorship** + +The expression was originated by a machine. No human can account for its creative decisions, and no human authored it. It contains no valid new copyright (*Thaler*, 687 F. Supp. 3d at 146; No. 23-5233, D.C. Cir. 2025; 88 Fed. Reg. at 16192). + +**Consequence: Void Grant** + +The statute supplies the consequence. Section 103(a) provides: + +> The subject matter of copyright as specified by section 102 includes compilations and derivative works, but protection for a work employing preexisting material in which copyright subsists does not extend to any part of the work in which such material has been used unlawfully. + +And section 103(b) provides that copyright in a derivative work *“extends only to the material contributed by the author of such work.”* The legislative history states the point without ambiguity: *“An unauthorized translation of a novel could not be copyrighted at all”* (H.R. Rep. No. 94-1476, at 57, 1976). + +In our example, the operator of the derivative’s copy process decides to assert copyright over the output, and licenses it to the world under terms of the operator’s choosing, for example the Apache License. + +But the operator holds no copyright in machine-originated content (section III) and no license over the source from which it was derived (sections I and IV). + +For the derived material, the operator’s copyright claim **is an assertion of a right that never existed**. The material was used unlawfully, and section 103(a) withholds protection from *every* part of the work in which it appears. For the machine-originated remainder, the operator holds no copyright either, for lack of any human author. + +The operator’s license to the world is a promise the operator had no power to make. Every person who receives the work believing they received a valid grant has received **a void grant**, and stands, as a matter of settled law, in the position of a downstream user of an unauthorized derivative, whatever they were told at the time. + +This is a cascading consequence, and it is why the pattern is a hazard. No combination of self-granted licenses - “MIT,” “Apache,” “public domain,” anything at all - can transfer rights the operator never held. Every downstream project, product, or deployment built on the derivative is built on unlicensed reproduction of a third party’s work, whether or not it knew, whether or not it was told, and whether or not the marketing was plausible. + +The longer the derivative circulates unexamined, the more it becomes embedded, forked, vendored, depended upon, and the more expensive its correction becomes for everyone who trusted it. A field of superficially real projects, repositories, and licenses that **in reality confer nothing on anyone who relies on them is a minefield**, in the most precise sense the law allows: The rights they purport to grant *were never possessed*. + +The law defines what may be asserted, not what will be. The copyright owner may choose whether and how to assert these rights, and at what point in time. The exposure exists regardless, and for *every* downstream that trusted the void grant. This is the scope of the hazard that the conduct exemplified here produces. + +### VI. Fair Use Does Not Rescue This Pattern + +Every defendant raises fair use. It is an essential and important limitation in the service of free speech, accountability, criticism, education and other important domains. Therefore, it must be considered, and in the case exemplified here, it fails. + +Fair use is a limitation on the exclusive rights, evaluated case by case under four factors: The purpose and character of the use; the nature of the copyrighted work; the amount and substantiality of the portion used; and the effect of the use on the potential market for or value of the work (17 U.S.C. § 107). + +On the first factor, the governing standard is *Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith*, 598 U.S. 508 (2023), in which the Supreme Court held that: + +> In sum, the first fair use factor considers whether the use of a copyrighted work has a further purpose or different character, which is a matter of degree, and the degree of difference must be balanced against the commercial nature of the use + +The question is whether the use serves a further purpose, not whether the surface changed. A derivative that exists to serve as the same thing as the original, marketed to the people who would otherwise use the original, has not acquired a further purpose by being translated; the surface changed, the function did not, and the use is commercial. + +The remaining factors resolve the same way. Source code is expressive creative work, not bare fact. The pattern under examination copies the whole; a complete implementation, ingested and translated in its entirety. And the market effect is the decisive factor, because it is engineered: A derivative marketed as a drop-in replacement for the work it was copied from is not a complement to the original’s market, it is a substitute for it. The Supreme Court has long held that use of a work to satisfy the market demand for the original is the paradigm of an *unfair* use (*Harper & Row, Publishers, Inc. v. Nation Enterprises*, 471 U.S. 539, 566–67, 1985). + +The one case that is always raised in response, *Google LLC v. Oracle America, Inc.*, 593 U.S. 1 (2021), holds less than it is believed to. The Court there assumed *“for argument’s sake, that the material was copyrightable”* and held *“that the copying here at issue nonetheless constituted a fair use”* (*Id.* at 11). + +The material in question was a thin slice of *declaring code*, which the Court found sits, *“if copyrightable at all, further than are most computer programs (such as the implementing code) from the core of copyright”* (*id.*), in a use that built a new platform for a new environment, with the copier **having written the vast majority of its own code**. By comparison: A wholesale translation of an entire implementation, marketed as a substitute for it, is **not** that case; it is the other end of every factor. + +The valuable zones of fair use remain, and they are important. **Commentary and criticism**, quoting from a work to review, discuss or criticize it. **Teaching and scholarship**, explaining concepts and quoting excerpts, is its traditional beneficiary. + +### Conclusion + +The law is neither obscure nor new. The conclusion it yields can now be stated: + +* A machine translation of a protected implementation **is a derivative work**, and an unauthorized derivative **is an infringement**, whatever language it speaks and whatever machinery produced it. +* A work whose expression a machine originated has no human author, no valid new copyright, and without valid copyright **no license can be granted on it**. +* § 103 withholds protection from every part of a derivative in which protected material was used unlawfully. A license is a grant with conditions, and a derivative made outside the conditions **never received a grant**. +* A person who holds no copyright and no grant **can convey neither**, and *every* downstream consumer who received from them received a **void grant**. + +This is a *catastrophic* failure state for all who want to create things good and useful: The projects that inherit only void grants and liability believing they have inherited foundations, the users who depend on code that no one on earth can answer for, the honest builders whose work is buried under a field of plausible-looking impostors. + +### Sources and Authorities + +Statutory references are to Title 17, United States Code. Case citations are to the official or generally cited reporters. Online links are for reference only. Section numbers refer to the sections in which each authority is principally relied upon. + +**Statutes** + +* [17 U.S.C. § 101 (definitions: “derivative work,” “including,” “publication”) - I, II](https://www.law.cornell.edu/uscode/text/17/101) +* [17 U.S.C. § 102(b) (idea/expression) - II](https://www.law.cornell.edu/uscode/text/17/102) +* [17 U.S.C. § 103(a)–(b) (derivative works employing unlawfully used preexisting material) - V](https://www.law.cornell.edu/uscode/text/17/103) +* [17 U.S.C. § 106(1)–(3) (exclusive rights: reproduction, derivative works, distribution) - I](https://www.law.cornell.edu/uscode/text/17/106) +* [17 U.S.C. § 107 (fair use) - VI](https://www.law.cornell.edu/uscode/text/17/107) +* [17 U.S.C. § 501(a) (infringement) - I, V](https://www.law.cornell.edu/uscode/text/17/501) + +**Judicial decisions** + +* [\*Jacobsen v. Katzer\*, 535 F.3d 1373 (Fed. Cir. 2008) - IV, V](https://www.casemine.com/judgement/us/5914b290add7b04934760a54) +* [\*Sun Microsystems, Inc. v. Microsoft Corp.\*, 188 F.3d 1115 (9th Cir. 1999) - IV](https://law.justia.com/cases/federal/appellate-courts/F3/188/1115/629501/) +* [\*Graham v. James\*, 144 F.3d 229 (2d Cir. 1998) - IV](https://caselaw.findlaw.com/court/us-2nd-circuit/1011522.html) +* [\*S.O.S., Inc. v. Payday, Inc.\*, 886 F.2d 1081 (9th Cir. 1989) - IV](https://law.justia.com/cases/federal/appellate-courts/F2/886/1081/19091/) +* [\*MDY Industries, LLC v. Blizzard Entertainment, Inc.\*, 629 F.3d 928 (9th Cir. 2010) - IV](https://law.justia.com/cases/federal/appellate-courts/ca9/09-15932/09-15932-2011-02-25.html) +* [\*Artifex Software, Inc. v. Hancom, Inc.\*, No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017) (settled; dismissed with prejudice Jan. 2018) - IV](https://storage.courtlistener.com/recap/gov.uscourts.cand.305835/gov.uscourts.cand.305835.54.0_1.pdf) +* [\*Thaler v. Perlmutter\*, 687 F. Supp. 3d 140 (D.D.C. 2023), aff’d, No. 23-5233 (D.C. Cir. Mar. 18, 2025) - III, V](https://www.bitlaw.com/source/cases/copyright/Thaler-Perlmutter-Dct.html) +* [\*Burrow-Giles Lithographic Co. v. Sarony\*, 111 U.S. 53 (1884) - III](https://supreme.justia.com/cases/federal/us/111/53/) +* [\*Community for Creative Non-Violence v. Reid\*, 490 U.S. 730 (1989) - III](https://supreme.justia.com/cases/federal/us/490/730/) +* [\*Feist Publications, Inc. v. Rural Telephone Service Co.\*, 499 U.S. 340 (1991) - II](https://supreme.justia.com/cases/federal/us/499/340/) +* [\*Baker v. Selden\*, 101 U.S. 99 (1879) - II](https://supreme.justia.com/cases/federal/us/101/99/) +* [\*Computer Associates International, Inc. v. Altai, Inc.\*, 982 F.2d 693 (2d Cir. 1992) - II](https://law.justia.com/cases/federal/appellate-courts/F2/982/693/137252/) +* [\*Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith\*, 598 U.S. 508 (2023) - VI](https://www.supremecourt.gov/opinions/22pdf/21-869_87ad.pdf) +* [\*Google LLC v. Oracle America, Inc.\*, 593 U.S. 1 (2021) - VI](https://supreme.justia.com/cases/federal/us/593/18-956/) +* [\*Harper & Row, Publishers, Inc. v. Nation Enterprises\*, 471 U.S. 539 (1985) - VI](https://supreme.justia.com/cases/federal/us/471/539/) + +**Administrative and policy authorities** + +* [\*Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence\*, 88 Fed. Reg. 16190 (Mar. 16, 2023) - III](https://www.federalregister.gov/documents/2023/03/16/2023-05321/copyright-registration-guidance-works-containing-material-generated-by-artificial-intelligence) +* [\*Zarya of the Dawn\*, U.S. Copyright Office (Cancellation Decision, Feb. 21, 2023), Registration No. VAu001480196 - III](https://www.copyright.gov/docs/zarya-of-the-dawn.pdf) +* [U.S. Copyright Office, \*Copyright and Artificial Intelligence, Part 2: Copyrightability\* (Jan. 29, 2025) - III](https://www.copyright.gov/ai/Copyright-and-Artificial-Intelligence-Part-2-Copyrightability-Report.pdf) +* [H.R. Rep. No. 94-1476 (1976) - V](https://law.resource.org/pub/us/works/aba/ibr/H.Rep.94-1476.pdf) + +## Evaluating a Reticulum Implementation + +### The Intention Of This Guide + +Very few user of network infrastructure can verify the software they run. This is true of the reference implementation as well, and it is precisely why it was engineered the way it was: the entire Reticulum protocol implementation - the transport logic, the cryptographic interfaces, the routing - is less than 15,000 lines of code, including its extensive comments and detailed logging. The reference is *designed* to be readable by a human in a reasonable sitting. That is a deliberate decision, and it is the standard against which every other implementation should be measured: An implementation that asks for trust while being structurally unreadable is asking for the absurd. + +Because most users cannot verify the code directly, the evaluation of the *project* is the evaluation of the software. The framework below exists so that this evaluation can be performed in minutes, by anyone, without expertise - and so that each new “implementation” does not require the kind of full investigation that would otherwise be if not impossible, prohibitevly expensive. + +### Two Questions That Resolve Most Cases + +Other considerations in this guide is further corroboration. These two questions allow you to decide the case quickly in most instances, and they should be asked first. + +**Question 1: Does this speak the protocol, or was it just generated from the reference?** + +The copyright and license realities, described in [What The Reticulum License Is](#brandolinis-what-the-license-is), is the legal foundation of this distinction. The protocol is public domain: A *genuine* [clean-room](#brandolinis-cleanroom-delusion) implementation, reasoned out and written by humans, is free and welcome, and owes nothing to any license. But an implementation that was *directly generated from* the reference - reproduced by a copy process, whether manually or through a machine or software - is a derivative of the licensed work, and is subject to both the license’s conditions, and to the ordinary copyright law examined in [Copyright & The Two Legal Layers](#brandolinis-copyright-and-layers). A primarily machine-generated copy without substantial human creative input is not merely unlicensed; it is a copyright violation that would exist under any license at all. + +**Ask**: Does the project say where its protocol knowledge came from? Does it credit the reference implementation, or claim “ground-up” status while its own history shows continuous ingestion of the reference’s source? Does its license carry the original copyright notice? The answers tell you, within minutes, which of two very different kinds of project you are dealing with. + +**Question 2: Who, or what, is the agent of the work?** + +This distinction, established in [Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution), is the trust foundation of everything else. Is there a human who decided what to build, judged what was correct, rejected what was wrong, understands what was shipped - and can answer for it, line by line and decision by decision, *without machine assistance*? Or is the machine the agent, with the human’s role reduced to the name, the account, and the signature? + +> This test has a sharper form: **would the project be meaningfully different if someone else had pressed the button?** If the answer is no - if any person could have been the signature and nothing would change - then the “author” is not the agent of the work. They are its facade, and the project is, in the most literal sense, worthless and unowned. + +A project with no owner is a project no one can answer for, and infrastructure with no one to answer for it has no place carrying other people’s traffic. + +### Other Signals To Look For + +Once the first two questions are answered, the following signals determine the verdict. None is alone decisive; together they form a pattern that is difficult to fake in the directions that matter. + +#### Provenance and attribution + +* **Credit to the reference.** Does the project name Reticulum’s reference implementation + in its README, its website, its licenses, and the code? Does it present itself as a port + or as a “ground-up” origin story? Absence of credit, in a field where every implementation + owes its existence to the reference, is not an oversight; it is a decision. + +* **License compliance.** For a derivative, the license conditions apply: the copyright + notice and permission notice in all copies and substantial portions, the harm condition, + the AI-training condition. A project whose license file claims a fresh copyright in the + operator’s name, over work that was generated from the reference, has failed the minimum + bar of honesty before any code is read. + +* **Disclosed provenance.** Is the use of machine assistance stated openly, or does the + project maintain machinery to conceal it - commit hooks that refuse attribution of + generation, contribution policies that declare machine output the human’s own, scrubbers + for personal traces, fictitious contributor identities? The first is the mark of a human + using a tool. The second is the mark of a record being manufactured. + +* **The author’s history.** Is there a prior record - projects, contributions, a body of + work that a person can look at and reasonably assess? A sudden, fully-formed “decade of experience” + appearing from nowhere, attached to a project of unprecedented scope, is a story that + contradicts itself. + +#### Agency and answerability + +* **Who answers the questions?** When technical questions are asked, does a human answer + with substance - going deeper, explaining trade-offs, admitting uncertainty - or do + answers deflect to process (“the CI verifies it”, “the proofs prove it”, “the audit + covered it”)? Are the answers themself machine generated? Deflection to process is + the substitute’s answer pattern: It names the machinery instead of the reasoning. + +* **Velocity commensurate with authorship.** Is the output volume compatible with human + authorship, review, and judgment? An implementation ten (or 42!) times the size of the reference, + produced in a fraction of the time by a single person, is not evidence of brilliance; it + is evidence of unchecked generation. Churn is part of the same signal: A project that + deletes half of everything it adds is not building; it is looping. + +* **Signs of development, growth and learning.** Do reversals exist? Contested decisions? + “We tried X and it was wrong, so we did Y”? Humans change their minds, admit mistakes, and + leave the wear of judgment in their history. Pure generation shows “the polish of its + absence”: uniform register, endless renaming, and errors discovered by the generator’s own + later runs, recorded as if they were planned milestones. + +* **Standing behind failures.** When something is wrong, does the human say “I chose this, + here is what I got wrong, here is the fix”? Or do corrections arrive as process language, + with nobody accepting that a decision was even made? A project whose history contains no + first-person acceptance of error contains no author. + +#### Engineering reality + +* **Honest benchmarks, or none.** If performance is claimed, is the baseline real - stock, + current, interpreted RNS, on the modern interface, at equal policy, with methodology + published in advance and reproducible by anyone? + +* **Interop with reality.** Is compatibility verified against the *current* reference + implementation - on real hardware, including the radio and serial interfaces this + protocol family lives on - in both directions, over long transfers, uptimes and edge cases? + +* **The readability standard.** Can a competent human read the core of this implementation + in a reasonable sitting, the way the 15,000-line reference can be read? Was human + readability a stated design goal, or an afterthought? A project that cannot be inspected + is a project asking for trust it has not earned and will never attend to. + +* **Nonstandard inventions.** Does the project “improve” on the protocol with its own + modes - new channel behaviour on shared spectrum, new rendezvous mechanisms, new crypto, + “post-quantum” replacements, “turbo” variants? Inventions that change behaviour on a + shared network are not features; they are forks of the airwaves, imposed on every other + node that shares the medium. A project that invents on top of a protocol it has not yet + correctly implemented is not advanced; it is dangerous to its neighbours. + +* **The public record.** The commit history is public. Read it. + +#### Network citizenship + +* **Honest presence.** Does the project identify itself honestly on the network, or does + it masquerade as something it is not? + +* **Coexistence.** Does it respect the shared medium and network conventions? A node that + is a bad neighbour on the spectrum is a hazard regardless of how well its code works in isolation. + +* **Community participation.** Does the author participate in the community as a member - + answering questions, contributing, learning - or only appear to advertise? The second is + not participation; it is exploiting the community as a broadcasting target. + +#### Monetary and influence signals + +* **Money under the claim.** Donations, funding, or commercial offers premised on claims + like “89× faster” or “formally proven” convert false marketing into a different category + of problem. When money changes hands on the strength of fabricated measurements, the + stakes are no longer theoretical. + +* **Tokens and “investment” vehicles.** Any implementation that surrounds itself with a + crypto token, a “coin”, or an investment pitch should be treated as what it is: A project + whose primary purpose is to earn the controller a profit, not open networking. + +* **Marketing-first ordering.** A polished website on day three, a twelve-language marketing + presence, a “benchmarks” page and a “get started” funnel existing before the protocol works + is a massive red flag. Real builders ship, then talk. The inverse order is the signature of + a project whose goal is attention. + +### The Conformal Surface + +One warning before the synthesis. When you evaluate any project, assume - as a working hypothesis - that its surface is an investment. The marketing, the design, the badge collection, the “proof records”, the fluent and confident prose: This is exactly where substitution invests, for the simple reason that it is where the audience looks first. Fluency is the *minimal conformal surface* of understanding, and the surface is not evidence of anything except that the author *wanted to look convincing*. If you find yourself impressed by the surface before you have asked Question 1 and Question 2, you are doing the evaluation in the order the substitute operator hoped you would. + +### Possible Verdicts + +The framework proposed here can yield three different verdicts: + +1. **Meets the standard.** A named human who can answer for the work and demonstrably does; + provenance disclosed; attribution given; honest benchmarks; interop + demonstrated against current, real RNS on real media; readable code; a maintenance + history that shows growth and learning. This standard is not high. It is what the + reference implementation has met, in public, for over a decade, and it is what any + project that wants other people’s traffic should be willing to meet in turn. +2. **Experimental, but honest.** A project that clearly labels itself as in-progress and + experimental (“do not use this yet”, in plain words, as the first thing a user sees) + discloses its provenance, credits the reference, and is being developed in the open by + humans who answer questions. Such projects should be encouraged. They are how the + ecosystem grows, new ideas are tested, and the framework above is designed to make an + honest experimental project *easy* to recognize, not hard. +3. **Does not meet the standard.** Unanswerable authorship, concealed provenance, fabricated + measurements, invented protocol behaviour, absent interop, marketing ahead of substance. + Such projects should be treated as unproven regardless of their surface, and as hazards + if they invite users onto shared networks. The community owes them exactly the + skepticism they have earned, and not a moment of engagement beyond that; the network’s + time is better spent elsewhere. + +### These Standards Are Reasonable + +I’ll close this guide by stating what these standards are *not*: They are neither a demand for perfection, nor a ban on machine assistance. Assistance is useful, when it is used to arrive at *higher levels of synthesis* than unaided work. It is not a requirement that an implementation be a clone of the reference; neither is it a requirement that it invents everything from scratch or aspires to be a [“clean-room”](#brandolinis-cleanroom-delusion) implementation. Good implementations of the protocol are very welcome, *however they come*, but working on one requires *serious* work, considerable skill, and **deep competence**. + +The reference implementation has met this standard for years, and its users know what that looks like. + +## The Movement Of A Dozen + +### Presentation, Elongated + +Whenever Reticulum defends itself, its license, or its community - or simply continues to exist - a familiar chorus appears. The register is always similar: *concern*. Concern about the direction of the project. Concern about its license. Concern about its governance. Concern about its “bullying” of “good-faith contributors”. Concern about the future of the ecosystem at the hands of a single maintainer. The chorus speaks in the plural, presents itself as a body of independent voices, and insists, with some frequency, that it is… *not alone*. + +The implicit claim under examination in this section is that there exists a *movement* of concerned individuals, spread across the ecosystem, all worried about Reticulum, and therefore (for some reason) deserving of a place at the table of decisions. + +A resolution of this claim requires one step: Count them. + +### Headcount + +This “movement” does have a headcount. It is not in the hundreds, and it is not in the dozens. It is a small number of people who appear, in various combinations and under various names, in the following roles: + +* Creators of the machine-generated “Reticulum implementations” examined in this chapter. +* Creators of articles praising those implementations and lamenting the state of the + reference, its moral shortcomings, its unavailability or lack of something it already has. +* Commenters “defending” the implementations when they are evaluated reasonably and critically, + most often by attempting simply to derail the discussion. +* Critics of the Reticulum License on “open source” grounds. +* “Concerned community members” objecting to the maintainer’s conduct. +* Campaigners on online platforms; and +* In some cases, a single individual performing *several* of these roles at once, under + different names, in the same week. + +The overlap is well documented at this point, across time and different platforms. The same phrasing, the same arguments, the same links, the same reactive reflexes, the same handful of accounts appearing in the same threads at the same moments. When the sockpuppets are unmasked (and they frequently unmask themselves) the cast does not grow, but rapidly shrinks. + +This is the most interesting single fact about the “movement”: **It isn’t one. It is a synthetic cast**, held together mostly by LLM-glue, reddit handles and hysteria. A cast is not a constituency. It performs; it does not represent. The difference matters quite a bit, because a great deal of this “movement’s” imagined power comes from the assumption that the *plural form* is actual evidence of plurality. If that sentence seemed opaque, notice how many times a statement or article uses “we” instead of “I”, and it will be less so. + +### Recycled Wine, Fermenting + +The cast is not only small, it is also, by any evidentiary standard, *forgetful*. Every major claim this “movement” advances has been advanced before, answered in public, with evidence, and often years ago - and is then advanced again, unchanged and completely ignoring any rationale or evidence presented previously (to the same people), as if the answer had never been written. + +* **The license argument.** Reticulum is “not really open source” because its license is not + approved by a particular orthodoxy. This is answered (now in a new and updated version, for the + fifth time) in full in [Open Source Means Open Source](#brandolinis-opensource). It was also + answered in public, at length, at the time of the license change - including the + arithmetic of who is actually restricted by which license. It is repeated *ad infinitum* anyway. + Quite a conversation starter, apparently. + +* **The distribution argument.** Reticulum is “not properly distributed” because it is not + packaged as a `.deb` or on some favoured catalogue. Reality: It is available on practically every + platform with a single command, packaged by the community in a wide range of channels, and + capable of updating itself over its own network. The argument has been answered; it is repeated. + +* **The “stepped back” narrative.** When the primary mirror of the project moved away from + a public internet platform, it was spun as the founder leaving for good, or now taking on dictatorial + powers, or abandoning his creation, or any variation or nonsensical combination thereof. + Those spins always center around justifying that *a vaccuum now needs to be filled*. + There was no such vaccuum. The narrative is repeated in various forms whenever convenient. + +* **The enclosure narrative.** The license is reframed as a “power grab” or an “enclosure” + of the commons - as if a license whose protocol is public domain and whose conditions + restrict only harm and appropriation were a form of enclosure. The [most recent](https://gaggl.com/blogs/2026-09-05-enclosure-by-good-intentions/) (and mostly incoherent) + expression of this narrative is, once again, fluent, polite, and factually hollow. The + bizarre arguments supporting the “article” include: Defunct and abandoned forks presented + as living, community forks bearing the very Reticulum License mislabeled as AGPL license vehicles + (created by “concerned users”), companion app forks correctly retaining the Creative Commons + licensing used as further evidence of the same and completely abandoned projects propped up + as being “the ecosystem”. Another case of LLM generated nonsense that the “author” didn’t bother checking. + The intent is clear here, simply produce more *mass* of the bullshit, so it can be further + referenced, regurgitated and linked to. + +* **The “bullying” narrative.** Whenever the community declines to treat manufactured + controversies as legitimate, or calmly documents the falsity of claims, or (Lord forbid) + moves a forum post for violating clearly stated forum rules, + the response is the same: The documentation is “bullying”, the community is “excluding” people, the + maintainer is “unprofessional”. In the most recent example, those accusations were made by someone who, in the + same week, publically called for the Reticulum maintainer’s “removal from the equation”, forged a moderator’s + username, attempted to drag unrelated individuals into the campaign, and presented a new + round of outright falsehoods. Contrary to popular belief, the accusation of incivility + is not the last resort of the wronged; it is the standard reflex of the exposed. + +None of the “arguments” engages the answers given repeatedly, and extensively. That is the point, and the strategy. The arguments are not produced for the purpose of being engaged; they are produced for the purpose of *being repeated* - the same wine, poured into new bottles, on a cycle. Each cycle is short, cheap to produce, and (thanks to freely available fluent text generation) now nearly effortless. The intended audience is not the community, which has heard it all before. The intended audience is the newcomer, who has not. + +### The Method of Madness + +The method behind the pattern is consistent and simple enough to be described precisely: + +**Bullshit asymmetry** + +Producing a fluent, plausibly-sourced smear is now the work of minutes. Refuting it to the standard this manual demands is the work of days, and the refuted smear is replaced by the next one within the week. This asymmetry isn’t just a fine point of the campaign; **it is the campaign**. The goal is exhaustion - the slow conversion of the community’s time and attention from building to defending. + +**Weaponized concern** + +The register of the campaign is almost always the register of solicitude: “we are worried about the ecosystem”, “we just want what is best for the community”, “this is about the future of the project”. The concern is directed, without exception, at the things the campaign wants changed, and the change it wants is always the same: **The replacement of the reference’s authority with its own**. Concern is the *costume*; capture is the choreography. It is the oldest form of cheap power grab in the book. + +**Event seizure** + +Any event - a license change, a platform move, a forum moderation decision, a subreddit closure, a security notice, even the most banal messages from maintainers or known contributors - are seized, stripped of their actual context, and re-narrated as evidence of the same pre-written story. The subreddit that was closed after its moderator vanished and ceased moderating (according to *prior agreement with said moderator*) becomes “the maintainer shutting down dissent”. Moving away from a highly centralized online platform becomes “the founder retreating”. The license becomes “the enclosure”. The pattern is so reliable that the story could be pre-written by a lightly mechanized quill; only the date changes. The actual real-world context of these events is documented, in public, in each case; the re-narration proceeds regardless. + +**The legitimacy circuit** + +The campaign invests heavily in the places where legitimacy is minted: Conference talks, blog platforms, social threads, and forums - presented as if these appearances constituted some sort of ecosystem-wide groundswell rather than the same dozen people moving through the same circuit. The LLM-generated articles cite the LLM-generated ports; the ports are praised in the articles; the managers of the ports spread the articles, and echo them on the forums and internet platforms; the conference presentations cite the forums. Random bypassers with the need for a cause watch the conference presentations and take on the holy duty of Internet Soldier. The circuit is closed, self-referential, and (to a reader encountering it fresh) convincing. It is also, entirely, **a loop of bullshit**. + +**The prior-work minefield** + +The machine-generated implementations have a consequence beyond attention: They flood the space with fake “prior work”. The effect, as the license discussion predicted in the beginning of 2025, is the creation of a minefield of sloppy repositories that can later be matched against any genuine project, and attempt to claim prior art, or even worse: Dissuade actual, honest developers or builders from taking up a real project they might have succeeded with, because they now believe it has already been done. Just as importantly, it also buries real efforts under machine-generated noise. The machine-ports are not failed attempts to contribute. They are (disregarding intentions, but effectively) the campaign’s long game, deployed as inventory. + +### A Persistent, But Fragile Triad + +This chapter as a whole has documented three fronts: The legal-ideological attack on the license ([Open Source Means Open Source](#brandolinis-opensource)), the substitution and usurpation pattern in machine-generated implementations ([Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution)), and the takeover narratives examined in this section. They are three fronts of the same operation, run by the same cast. + +* The license attack and other urgency-engineered narratives are the *cover*: They supply + the ideological justification for treating the reference as illegitimate, and needing replacement. +* The ports are the *inventory*: they supply the “replacements” that the narrative claims + the ecosystem needs. +* The takeover narrative is the *objective function*: the repeated, persistent, escalating claim that + the reference should be replaced, and that the speakers themself are the natural heirs. + +Each front depends on the others, and all three depend on a single, fragile assumption: That their audience cannot count. Restore the count, and the charade collapses into what it is: + +**A small group of people, obsessively orbiting a technology they did not build, synthetically producing the +appearance of a constituency they do not have, in service of a takeover they cannot justify.** + +### What The Pattern Is Not + +It is important, to also say what this pattern is *not*, exactly because the campaign depends on being mistaken for such things. + +**It is not criticism** + +The Reticulum community has always had lively, rigorous criticism - of decisions, of priorities, of direction - and it has always engaged that criticism on the merits, and changed course and development priorities many times. The license discussions at the time of the change were extensive, public, and answered in full, including with the critics themselves. Core protocol decisions were always discussed and evaluated in the community. The complex coordination and execution of several protocol upgrades between a loosely organised group of developers, node operators and users have succeeded surprisingly fluidly. All of these are success stories that the “critics” **always** ignore. Real criticism engages the content and accepts evidence. The campaign engages nothing. + +**It is not a community** + +Communities *build things*, maintain them, and have skin in the game; long-term users, operators of nodes, authors of real applications, people whose traffic flows through the network every day. A community has a stake. The “movement” only has an agenda. + +**It is not a debate** + +A debate has parties who evaluate arguments and evidence, and as a function of that, the debate moves forward, perpetually. The campaign’s arguments, as shown above, are not designed to survive contact with answers, but to be repeated past them. You cannot debate a loop. You can decline to perform for it, though. + +### Intent & Consequence + +While it would provide for interesting speculation, we do not need to know what the individuals in the cast *intend*, and this document will not speculate about their inner lives. People may believe their own narratives entirely, or partly, or not at all; **the pattern is the same in any case**, and the pattern is what matters here, since it is the exact thing that has been so insidiously destructive and resource wasting for the actual Reticulum project and community, ever since Reticulum was more widely discovered, popularized, and became a prime target for all sorts of grift known to man. + +The consequences are very real: + +* **Time**. The community’s scarcest resource is the attention of skilled people who actually build + and maintain the network. The campaign converts that attention into reactive defence, on a cycle + with no end. + +* **Harm**. Hastily machine-generated implementations, marketed as drop-in replacements and carrying + traffic onto shared networks, mislead users and can damage the network and its neighbours. + We, the actual reticulum community, all rely on these networks every day, and it is my belief + that we need to defend them. The fabricated measurements and laundered authorship examined in this chapter are not + editorial embellishments; they are the mechanism by which real users are induced to run + unverified, and often destructive software. + +* **Erosion of the currency of trust**. Every manufactured scandal, every fluently polite smear, every + fabricated “movement” debases the currency of trust and degrades it for **everyone**; + including, most of all, the honest projects that come after. This is deep harm, and + it is the primary reason this chapter exists. + +Whatever the intent - profit, control, attention, or a simple, obsessive inability to stop - the mechanism is the same, and the response should be *calibrated to the mechanism as a whole*, not to the individual person acting as the current avatar for it. + +### Recognition & Response + +For anyone who encounters the pattern fresh, here is a proposal on how to recognise it, and what to do about it. + +**Recognition:** The pattern is recognisable in minutes, once the signs are known: + +* Claims that have been answered before, repeated as if never answered. +* The register of solemn concern applied, without exception, in one direction. +* A severe allergic reaction to answering any questions posed. +* A cast that is small, overlapping, and frequently anonymous, with the *plural form* doing the + work of plurality. +* Sockpuppet theater: The same person or footsoldiers thereof appearing as several “supporters” + (and occasionally slipping up mid-performance). +* Articles, ports, and forum threads that cite and reference each other in a closed loop. +* The immediate, reflexive turn to “bullying”, “exclusion” and “toxicity” whenever a claim is refuted. +* A complete absence of engagement with the substance of the answers given, and a complete + absence of stake in the network itself. + +**Response:** A constructive response is one that is proportionate, and does not cost the +community its resources, sanity and dignity: + +* Engage the content once, on its merits (if any), with evidence, in public, and then refer to the + existing records. The answers already exist; they do not need to be re-derived for every new + bottle of piss-sour burgundy served from a man behind the curtains. I will do my best to keep this + chapter up to date with such answers and records, for easy reference, but other great resources + exist. +* Do not become part of the theater performance. The “movement” feeds on engagement in *any* form; + attention is its fuel, and outrage is as good as endorsement for them, if not better. +* Do the headcount. When the audience is reminded that a “movement” is a dozen people + recycling answered falsehoods, its projected power dissipates. The power was never real; + only the audience’s own assumption of scale can make the illusion effective. A polished-looking + “ground up” implementation might look like the work of many people, but is most likely + just the result of an LLM looping on a laptop for a couple of months (this is weird, but it is + the reality we now live in). Four different users suddenly singing in unison may look like the + representatives of a broader sentiment, but is most likely the same person hiding behind the same keyboard. +* Then, spend the saved time on the networks: On building real infrastructure, putting up nodes + and antennas, on real development, real maintenance, real coexistence, and on the people + *who actually use Reticulum*. The things that we can only do *together*, as humans. That is + what the fake “movement” cannot do, no matter how fluent and smooth its productions become. + +## Network Health & Coexistence + +### Substance Of The Networks + +Before examining health, we should consider what is being protected. The networks are not a repository. They are not a website, a social presence, or a set of marketing pages. They are a habitat: A living commons of communication, carried by, from a catious estimate, an intermesh now consisting of over a hundred thousand physical devices, embedded in a plethora of applications and packages, transporting terabytes of traffic every single day - real messages, real coordination, real people - across radios, serial lines, phones, laptops, and backbone servers, in cities, places and ways that no other network reaches. + +The protocol belongs to humanity; no one owns it. The network belongs to everyone on it, and its membership is defined by nothing other than participation: A node on a mast, a phone in a pocket, a server routing for its neighbourhood, a developer building on the commons. The network has no gatekeepers because it needs none; it is held together by the same physics and mathematics everywhere, and by a shared expectation of how members behave. That expectation - unwritten, unenforced by any central authority, and just as important as any code - is the subject of this section. The *Zen of Reticulum* calls the software a habitat. A habitat is healthy or unhealthy as a whole, and the health of this one is decided, every day, by the people who live in it. + +### Health Is A Property Of The Whole + +A network is not made healthy by the excellence of any single part. It is made healthy by the behaviour of every part on the shared medium, and how they interact. And the shared medium is the point. When your node transmits, it transmits into the same spectrum, the same line, the same time, the same mathematical address space, the same bandwidth that its neighbours depend on. + +The network cannot be certified by any single project’s claims. A node that is a bad neighbour, that invents its own channel behaviour on shared spectrum, that announces without discipline, that spawns tens of thousands of links to scrape the network, that floods and retries without mercy, is a hazard to every node that shares its medium, regardless of how well its “creator” imagines its own code to work in isolation. + +On a shared medium, “my software works” is not a complete sentence. The complete sentence is “my software works *and coexists*”. A network’s health deteriorates with its worst-behaved member, and every member has a responsibility to not be *that* member. There is no final, technical solution for this; the solutions are human. + +### A History Of What Works + +Let’s recall, because it is the ground truth this entire thing rests on, that the coexistence model has *worked* - is working, right now, **at scale**. Reticulum’s protocol decisions have been discussed and evaluated in the community, openly, for years. Protocol upgrades have been designed, coordinated, and executed between a loosely organised group of independent developers, node operators, and users - and have succeeded, repeatedly, without any corporate board, without any central command, and without the collapse that the skeptics predict every second week (while screaming for *GOVERNANCE*). The reference implementation has been developed in the open for over a decade, by a maintainer who answers for it, fixes bugs or issues within hours of their discovery, and is set down in code deliberately kept small enough (the entire protocol implementation under 15,000 lines, including its comments) for a human to read, verify, *and challenge*. + +This is the empirical baseline that every narrative examined in [A Movement Of A Dozen](#brandolinis-movement-of-a-dozen) conveniently ignores, in order to justify: + +* The claim that the project is a one-man dictatorship +* The claim that the community is excluded +* The claim that the networks need saving from their own founders + +The **reality**, documented and reproducible, is that a loose community of humans coordinates complex technical evolution *without* the apparatus the narratives insist is missing. The health of the networks is not a promise for the future; it is a demonstrated property of the past and present, under the leadership and community model that brought it into existence and navigated it through difficult decisions and situations over a decade. **My job is to keep it that way**, and you can be damned certain that I take it seriously. + +### The Role Of The Individual + +The networks are built by physical acts and human coordination. You cannot prompt an antenna into existence. No model can string up a dipole, or stand in the rain aligning a radio, or coordinate with a neighbour three valleys away about who covers which repeater frequency, or sit down with a newcomer and explain why their first node didn’t announce. These are the acts that make a network *organic* - present in the physical world, resilient because it is *real*, valuable because it is *human*. The machines and technology we use are tools aimed at a well-defined, openly described goal. But the networks themself are composed of intentional human actions, and every node operator is infrastructure for other humans. + +This has a corollary for the individual: You do not need permission, and you do not need to be an expert, to participate. Run a node. Help a neighbour. Ask questions in the community, and answer the questions you can. Build something small at first. The network grows by these acts, and they are the most meaningful ones - the things that can only be done together, as humans, in the physical world. The parasitic “movement” that haunts the peripheries of this ecosystem cannot do any of this. It cannot build a node because it does not exist, in any real connected and human sense; only people can, and people are precisely what a self-recurrent loop lacks. + +### The Place Of New Implementations + +The future of the network includes more implementations - and they are welcome. This chapter is not an argument against implementing Reticulum. The protocol is public domain, by design, and the network is made stronger by genuine diversity: More *good* implementations, honestly made, mean more resilience, more experimentation, more people who understand the protocol deeply *because they have built it themselves*. That is the goal: **For people to understand and own the technology they rely on**. Not to spew out 600,000 line rust ports that fills no meaningful gap or purpose. + +What the ecosystem needs, from every implementation, is the ordinary floor that [Evaluating A Reticulum Implementation](#brandolinis-evaluating) establishes, and that the reference has met for over a decade: A human who made it and answers for it; provenance disclosed; attribution given; benchmarks honest or absent; interop demonstrated against the real network; code a human can read. And it needs the one thing that costs nothing and changes everything: **Honest labeling**. + +An experimental implementation that says, plainly, as the first thing a user sees: “This is in-progress, experimental, do not depend on it yet, but help if you can”, that is a gift to the ecosystem. It contributes, it invites participation, and it protects users. + +The opposite, the polished “drop-in replacement”, does damage far beyond its own users: It dissuades the honest developers who might have built *the real thing*, because the polished slop persuades them the work is already done. That dissuasion is one of the quietest and most expensive harms in this entire affair, and the antidote is honesty at every project’s door. + +### Expanding The Commons + +Coexistence, reduced to its essentials, is a short formula; the duties of membership in a network no one owns: + +* **Be honest.** Say what you are, what you built, how you built it, and what you used to + build it. Label experimental work as experimental. Credit the work you build on, including + the reference implementation, in the licenses and in the prose. Concealment is not a + defence; it is a very clear diagnosis marker. + +* **Be owned.** Have a human who made the work and can answer for it. Use assistance, don’t + substitute. Never sign what you cannot answer for. The chain of accountability is the + community’s only verification at scale, and every link in it is a *person*, not a facade. + +* **Be a good neighbour.** Respect the shared mediums. Do not invent new behaviour in our + shared space and call it progress. The network belongs to its other members as much as + to you. + +* **Verify against the network.** Compatibility is a property demonstrated with actual nodes, + on actual media, against the actual current protocol, over a period of *years*, not 48 hours. + And not a claim pinned to an old snapshot over loopback. + +* **Participate as a member.** Ask, answer, help, build. *Advertising at* the community is not + the same as being part of it, and it is **not** the first thing you should do. + +None of this is a high bar. It is the bar the reference implementation has met, in public, for over a decade, and the bar the ecosystem has adopted organically itself, successfully, through every protocol upgrade it has ever coordinated, and everything running on Reticulum today, that people actually use. It is not a new requirement; it is the existing, working culture of the networks, now written down so that newcomers can find it and so that those who would exploit us cannot claim they never saw it. + +### Defence Of The Commons + +The networks need defending - not because they are under severe physical attacks (yet), but because attention, talent and resources is being stolen from them, trust is being mined against them, and its newcomers are being harvested by the machinery documented in this chapter. Defence, for a commons, has specific shapes, and it is not what the theater would like it to be. + +* Defence is **documentation**: Records kept public, of what was claimed, what was + answered, and what turned out true. +* Defence is **a headcount**: Calm, unexcited reminders that a “movement” might just be a dozen + people having a tantrum. +* Defence is **honesty in action**: The visible, ordinary practice of the good behaviour + by the people who actually run the networks. +* And defence is **building**: Every node raised, every page of *real* documentation, every + honest implementation, every new user helped into the community with the knowledge to know + what they are doing is more durable than any rebuttal, because it adds to the thing being + defended. + +--- + +**The theatre cannot keep up with a network.** + +**It can only orbit it, while it recycles its own sour piss.** + +--- + +A lot of us rely on these networks every day. They carry our messages, our coordination, our friendships, and in some places, our safety. That is exactly why they are a target: + +They are valuable, free, and very hard to shut down. The response is not to become aggressive. It is to be *more* of what the network already is: Real, open, owned, and shared. + +*Mark* + +## Addendum A: The Prns Case + +### Purpose & Scope + +This section provides a concrete example, which future evaluations can use as a template. Its purpose is not to be the last word on this particular subject, but to be an example of how the ideas in this chapter can be applied, and to make the next such examination easier. + +The subject of this case study is **Prns**, a project published at the repository `github.com/KenAKAFrosty/Prns`, presented as a “ground-up implementation of Reticulum, written in Rust”, marketed as faster, safer, and more strictly tested than the reference, widely promoted with the claim of “up to 89× the throughput” of the reference implementation, and an “author” actively engaged in the tactics described in [A Movement Of A Dozen](#brandolinis-recycled-wine) on online platforms. The record described below is the project’s own, and sourced from its GitHub repository, analyzed locally. + +### The Project In Brief + +* **Time span.** 3,374 commits between 2026-05-26 and 2026-09-12: approximately 110 days, + at a mean rate of ~31 commits per day. Monthly: 132 / 1,137 / 1,097 / 805 / 203. + +* **Authorship.** 3,252 of 3,374 commits (96.4%) are authored by a single account. A + second identity, “Prns Tests [tests@example.test](mailto:tests@example.test)” - a fictitious identity on a reserved + domain - contributed 35 commits, every one of them website and marketing content. + +* **Size.** 3,519 tracked files; 1,983 Rust files; 636,226 lines of Rust; approximately + 22.7 MB of Rust source; 69.5 MB of total repository content. + +* **Scope claimed.** A daemon (“drop-in replacement” for the reference daemon), embedded + firmware for three microcontroller families (including six ESP32-S3 board variants and + nRF52840), SDKs and bindings for nine languages, a browser-based node and web flasher, a + twelve-language website, a benchmark apparatus with its own publication and “proof” + pipeline, and a validation hub with oracles, fuzzing, mutation testing, and formal-proof + claims. + +* **Marketing claims.** “Ground-up implementation of Reticulum”; “up to 89× the + throughput”; “48× smaller peak-memory footprint”; “33× the energy efficiency”; + “Measured, not just claimed”; “Enforced, then audited”; “byte-for-byte wire parity with + the reference implementation”; “works with Sideband, NomadNet, MeshChat, etc.”; + “no_std (no alloc required either)”. + +* **Status at the time of writing.** Version 0.3.7; published version history begins at + 0.3.0. The repository continues to receive commits. + +### Question 1: Is this a clean implementation, or was it directly generated from the reference? + +The first of the two deciding questions from [Evaluating A Reticulum Implementation](#brandolinis-evaluating) is settled by the project’s own record. An actual [clean-room](#brandolinis-cleanroom-delusion) implementation, reasoned out and written by humans, would owe nothing to any license. The data available shows clearly that Prns is not that. + +* **The founding state.** The first commit, “Scaffold Personal Reticulum suite”, contains + the scaffolding of not one but two ports - `personal-rns` and `personal-lxmf`, the latter + being the reference’s companion messaging protocol - together with a daemon scaffold and + a 233-line founding document, `docs/build-ethos.md`. That document declares the project’s + goal as a “performance-focused drop-in-replacement for rnsd” and its governing principle + as: “Port the contract, not the implementation.” It further states directly to the + machine-loop, that **“You owe the reference fidelity at exactly two boundaries: + The wire… The behavior. … Between those two boundaries, the model is yours”**. + At this point, the very first commit, effectively the whole of the implementation design + and any relevant decisions are handed over to the LLM. + +* **Continuous ingestion from the reference.** 506 commits reference RNS or Reticulum + source behaviour; the word “parity” appears in 49 commit messages. Commits cite the reference + implementation’s own source locations (for example `Transport.py:1367`) when correcting + their own divergences and mistakes. + +* **Byte-level fidelity as an explicit goal.** Within 48 hours of the first commit, the + record shows a “crypto adapter - vetted primitives, byte-exact vs RNS 1.3.1”, and a wire + implementation matching the reference’s packet header layout. The project’s own + validation apparatus decodes wire vectors using the reference implementation’s own + packet parser, and the interop suite consists of real, stock-RNS peer nodes - that is, + the reference source itself, used as the ground truth against which this LLM output is + checked, and committed as accepted and verified after 48 hours of the project’s recorded start. + +* **The marketing mismatch.** The same record that documents all of the above describes the + project, publicly, as “a ground-up implementation of Reticulum” - while declining, on its + website, to link to the reference implementation at all: the entire tree mentions the + reference’s author in six files, and the website in none. + +Conclusion: the project’s own history and commit record establishes that it was generated directly from the reference implementation’s source code, not reasoned out from the public-domain protocol. It is a derivative of licensed work within the meaning of [the Reticulum License](#brandolinis-what-the-license-is) and [general copyright law](#brandolinis-copyright-and-layers). The “ground-up” claim, which carries its entire legal and marketing posture, is disproven by the project’s own history. + +### Question 2: Who, or what, is the agent of the work? + +The second deciding question is answered by the application of [Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution) criteria to the project. + +**Scope that no human could have authored** + +636,226 lines of Rust in 110 days is approximately 5,800 lines per day, every day, including weekends - with 149 commits recorded between midnight and 06:00, and Saturday the single busiest weekday. No human review or decision capacity is commensurable with this volume; the review capacity and the output volume are structurally incommensurable, which is the definition of unauthored scope. + +**Uniform generation** + +The record shows no sign of human development, growth, or learning: No contested decisions, no style drift. Instead: endless renaming (in the first 48 hours: `State → EngineState → TickInput → TickOutput`), uniform fluent register in every commit, and the exact same, synthetic voice in code, documentation, and website copy. + +**Discovery by regeneration** + +Corrections arrived by the machine’s own subsequent runs, recorded as planned milestones. In early July 2026, a series of “core review” commits documented, in the project’s own words: + +* announce-ID history “was unbounded per-slot growth” (`54cc8d601`); +* interface announce limiting could “leak a sustained flood” (`9d27af75c`); +* a “phantom-airtime leak” where frames “used to vanish silently” (`4ed75ffdd`); +* Group-packet deduplication “which RNS does not do” - a behaviour the reference never had, + implemented and later removed (`edd8e72be`); +* “both `unwrap_or(&[])` arms were unreachable dead defaults” (`74bea355e`); +* a benchmark crate “hasn’t compiled since” a prior rename, undetected for weeks because it + was outside the CI’s workspace (`86240b027`). + +Earlier still: the record shows a “>1 MiB RNS-to-Prns interop stall” closed three weeks in +(`cc4d524a3`), and a known send-path hang shipped with the note “typed fast-fail a +candidate for later” (`a010e6613`). + +**Laundered provenance** + +The repository contains a committed commit-message hook (`.githooks/commit-msg`) that *blocks* any commit containing attribution for machine generation (“generated with claude/codex/copilot/cursor/gemini”, “co-authored-by”), with the explanation “The committer owns the commit”. The contributing guide is explicit: “AI tools … are welcome … what you submit is *yours*”, and describes the contributing population as “both human and automated contributors”. The fictitious “Prns Tests” identity completes the picture: A manufactured, unknowable contributor, used for marketing content. + +**Authorship by assignment** + +The human whose name is on the work cannot answer for it, because the choices were never made by a human, and only the general shape and constraints of the outward presentation was. Nothing in the project’s history shows an individual explaining a design decision, accepting a mistake in the first person, or going deeper under technical questioning; the record shows process language and marketing instead. Per the earlier mentioned test: any other person could have pressed the same button, and nothing would be different. The project is effectively unowned, and void of value. + +By the criteria of [Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution), this is substitution. The machine was the agent of the work; the “author” was a facade. + +### The performance claims + +The project’s central marketing claim - “up to 89× the throughput” of the reference - is also its most completely documented failure, because the project published the evidence of its own measurement. The apparatus, the results, and the problems are all on the record. + +**The claim** + +The README states “up to 89× the throughput”; the on-network marketing page repeats “up to 89× the throughput, 48× smaller peak-memory footprint, and 33× the energy efficiency of stock RNS 1.4.2”; the website’s front page carries the tagline “Measured, not just claimed”. + +**The apparatus** + +The reference is loaded through `benchmarks/reference/compiled_reference.py`, which installs `pyximport` and then asserts two things: that `RNS.compiled == True`, and that at least *one* RNS module was loaded from a native extension. The project’s own published “proof” records show exactly what those checks captured, on every platform: + +```default +aarch64-apple-darwin: .../RNS.cpython-313-darwin.so, Cython 3.2.8, Python 3.13.13 +x86_64-unknown-linux-gnu: .../RNS.cpython-313-x86_64-linux-gnu.so, gcc 11.4.0 +x86_64-pc-windows-msvc: ~/.prns-oc/lib.win-amd64-cpython-313/RNS.cp313-win_amd64.pyd +``` + +In every case the recorded native module is the **top-level package only** - `RNS.so`, nothing below it. Nothing named `RNS.Transport`, `RNS.Destination`, `RNS.Packet`, `RNS.Link`, or `RNS.Resource` ever appears, because *nothing below the top level was ever compiled*. Nobody bothered to check or verify *anything* here. + +The machine output was simply taken for truth, and a full marketing strategy was spun and produced on it. “RNS 1.4.2 (compiled)” - the label used in every table, chart, and marketing page - *is not a mode of RNS that exists*, but the hallucinations of a machine, which the humans created a marketing strategy on. In reality, it is the old `CRNS` development shim, whose top-level-only, debug-oriented “compilation” is slower than plain interpreted RNS, and which was *defunct for over a year* before these benchmarks were published. + +**Interface choices** + +The harness writes the reference’s configuration itself (`benchmarks/reference/participant_node.py`): `TCPClientInterface` for the initiator, `TCPServerInterface` for the responder and both relay sides, with `UDPInterface` as the abstract wire. The reference was never given its modern `BackboneInterface` on any platform, forcing the slowest possible interrfaces. The interface selection is never mentioned in any methodology text. + +**The policy** + +The published default-policy tables record the asymmetry directly: Prns at 500 Mbps / 128 KiB TCP policy against the reference at 10 Mbps / 8 KiB - slyly footnoted as “preserves each implementation’s normal TCP policy” (in the case of RNS, a conservative default policy that was selected to prioritize coexistence on slower, shared links, requiring the user to dial it up to full speed if they knew what they were doing). Raw transport “throughput” ratios of 20.65× (Linux) and 38.84× (Windows) are therefore mostly policy, not engine. + +**The cross-host evidence** + +The published results show the same scenario producing wildly different ratios by host, and the variance is entirely in the reference artifact: + +| Host | Prns, single-packet | “Reference”, single-packet | Ratio | +|-------------------------|-----------------------|------------------------------|---------| +| macOS (Apple M4) | 37.4k/s | 420/s | 89.09× | +| Linux (i7-1260P) | 25.3k/s | 3.5k/s | 7.19× | +| Windows (Ryzen 5 5600X) | 30.8k/s | 3.9k/s | 8.00× | + +Prns is consistent (25–37k/s). The reference artifact collapses to different depths on different hosts, and the single worst collapse - 420 packets per second on macOS - is the cell selected as the global headline. The “89×” is not a measure of Prns; it is a measure of how badly the broken baseline happened to fail on one host. + +For reality calibration: Stock, interpreted RNS 1.5.4 on an ordinary mid-range laptop, single core, sustains roughly 30,000 single-packet deliveries per second (including ephemeral-key decryption), ~175,000–280,000 packets per second in transit relay, and on the order of 10 Gbps at 16 KiB payloads. The project’s “compiled” artifact measured 420–3,900 packets per second for its single-packet scenario: An order of magnitude or more *below* stock interpreted RNS. The comparison being marketed was not “Rust vs Python”; **it was “an implementation running under optimal conditions versus a mislabeled, broken shim on a slow legacy interface at a severe policy disadvantage”**. + +**The equalized rows** + +The project’s own “1 Gbps policy” rows, in which both sides are explicitly configured identically, publish ratios of roughly 2.4–8.4× across all hosts and scenarios - still against the broken baseline, but nowhere near 89×, and consistent with the ordinary, uncontroversial observation that a native implementation tends to outperform an interpreted one in raw throughput. That point needed no fudging to make, and is banal. + +Interestingly, though, it seems that Prns is really only *marginally* faster than a Python implementation, running in interpreted mode, on a single CPU core. + +**Assessment** + +The front page says “Measured, not just claimed.” The record shows the opposite ordering: claimed, and arranged to look measured. No methodology section anywhere states what “compiled” means, that it is a deprecated development shim, that it builds debug targets, or which interface the reference was given; the one statement of the policy asymmetry appears in a footnote of the results tables themselves. If they did not need to fudge it, they would have published the method clearly. + +### Overall Evaluation + +Evaluated against the conditions of [Evaluating A Reticulum Implementation](#brandolinis-evaluating): + +* **Provenance and attribution.** Fails: The fake “ground-up” origin story; zero reference links + on the website; a single well-hidden link in the README; a license file reading + `Copyright (c) 2026 The Prns Authors` over work directly generated from the licensed reference; + no original copyright or permission notice anywhere. + +* **Agency and answerability.** Fails on every criterion of [Assistance Versus Machine Substitution](#brandolinis-assistance-versus-substitution): + Unauthored scope, uniform generation, discovery by regeneration, laundered provenance, + authorship by assignment. + +* **Engineering.** Fails: The benchmark apparatus above; interop demonstrated only + against a pinned, outdated reference version over loopback while the marketing claims current + parity, interop failures with stock RNS; vendored prebuilt binaries and a republished fork + of an upstream crate (`nrf-softdevice 0.1.0-prns.1`) with no verifiable provenance; + committed WASM bundles. + +* **Network behaviour.** Fails: Invented spectrum behaviour and compatibility claims + about third-party applications of the reference ecosystem (Sideband, NomadNet, MeshChat) + that are not established by any evidence. + +* **Monetary and influence signals.** The marketing apparatus - website before protocol, + day-three twelve-language marketing, false benchmark headlines, “audited” and “formal proof” + claims - the conformal surface described in [Evaluating A Reticulum Implementation](#brandolinis-evaluating): + is where this project invested. + +### Licensing Analysis + +Applying the two legal layers established in [Copyright & The Two Legal Layers](#brandolinis-copyright-and-layers): + +**Layer A - copyright infringement (license-independent)** + +The record shows a direct copy roundtrip: the licensed reference implementation fed into a machine, transformed, at a scale and cadence no human could review, with a license file asserting a fresh copyright in the operator’s name and no acknowledgment of the work the project was generated from. No substantial, new human creative input is demonstrated anywhere in the record - the founding document explicitly frames the design as an instructed port of the reference’s contract. A primarily machine-generated copy of a copyrighted work, not accompanied by demonstrable substantial human creative input, is a derivative work over which the copier holds no copyright, and a reproduction of which without the original author’s permission infringes the original author’s copyright. This holds under any license, MIT included. The operator’s copyright claim over the result is, on this evidence, not merely unsubstantiated; it is the absence of one, directly asserted in the project’s own writing. + +**Layer B - license conditions (Reticulum License specific)** + +Modern Reticulum - the current wire format, the AES-256-based link encryption, ratchets, the cryptographic machinery as it exists today - has been published under the Reticulum License since April 15, 2025, effective from release 0.9.4 and every release since. As a derivative of that work, the license’s conditions attach: The copyright and permission notice must be included in all copies and substantial portions; the AI-training condition must be honoured; the harm condition must be honoured. The record shows none of the notice requirements met, and a production process that consists of the licensed work being ingested into a machine and regurgitated, at industrial scale and cadence. + +**The cascading consequence** + +Prns is distributed claiming dual MIT/Apache-2.0 licensing. It is, however, a direct derivative of Reticulum-licensed work, and the claimed grant is therefore void. Every downstream project that builds on Prns believing it is MIT/Apache-licensed is building on a grant that does not exist. The users of Prns, and all software developers using it, have in effect, been placed under conditions they were never told about. The “ground-up” claim is not merely false; it is the sole load-bearing element of an entire licensing posture, and it fails spectacularly. + +### Consequences + +The consequences of this pattern are examined in the following sections: The harm to users and to the network in [A Movement Of A Dozen](#brandolinis-movement-of-a-dozen), and the human dimension in [Network Health & Coexistence](#brandolinis-health-and-coexistence). The contribution of this addendum is narrower and intended as an instructive example: This is what a substitution project looks like, in full, on its own record. It is a reference example for [Evaluating A Reticulum Implementation](#brandolinis-evaluating), and it demonstrates, in one case, most of the elements this chapter describes. + +### Verdict + +Applying the three verdicts of [Evaluating A Reticulum Implementation](#brandolinis-evaluating), this project does not meet the standard. It is not “experimental but honest” - it is not labeled as experimental anywhere; the first thing users saw was a polished marketing presence promising a finished, tested, drop-in replacement. It is a project whose central claims are fabricated (the performance apparatus), whose provenance is laundered (the authorship machinery), whose foundation is misrepresented (the “ground-up” story), whose core semantics were learned late and by regeneration, and whose operator cannot possibly answer for any of it. It is also a blatant copyright violation of the reference implementation. + +The proposed conclusion, for users and for the network: Treat the Prns project as hostile regardless of its polished surface, and as a hazard insofar as it invites users onto shared networks. Nothing in this section is a judgment about the people involved; it is a reading of the results produced, their history and how they came to be, which in the regrettable lack of any human authorship is the only thing that can be expected to be held to account. + +### Dating + +This examination reflects the publicly available material as of September 2026; the repository in question continued to receive commits at the time of writing, so readers should treat citations to commits and files as point-in-time evidence. A [forensics snapshot](https://github.com/markqvist/forensics_prns) is publicly available on GitHub. \ No newline at end of file diff --git a/docs/markdown/git.md b/docs/markdown/git.md index a3dd6d61..253c1f36 100644 --- a/docs/markdown/git.md +++ b/docs/markdown/git.md @@ -639,6 +639,7 @@ The following template files are supported: - `commit.mu` - Individual commit detail page - `refs.mu` - Branches and tags listing - `stats.mu` - Statistics page +- `no_ident.mu` - Displayed to non-identified initiators if blocked Templates can include the following variables: diff --git a/docs/markdown/index.md b/docs/markdown/index.md index 4ad08b58..78262bc8 100644 --- a/docs/markdown/index.md +++ b/docs/markdown/index.md @@ -75,26 +75,37 @@ to participate in the development of Reticulum itself. * [The Work Is Finished](zen.md#the-work-is-finished) * [Open Sky](zen.md#open-sky) * [Programs Using Reticulum](software.md) - * [Programs & Utilities](software.md#programs-utilities) - * [Remote Shell](software.md#remote-shell) + * [Browsing & Publishing](software.md#browsing-publishing) * [Nomad Network](software.md#nomad-network) + * [Ren Browser](software.md#ren-browser) * [RNS Page Node](software.md#rns-page-node) * [Retipedia](software.md#retipedia) + * [Git Over Reticulum](software.md#git-over-reticulum) + * [Messaging & Voice](software.md#messaging-voice) * [Sideband](software.md#sideband) - * [MeshChatX](software.md#meshchatx) + * [MeshChatX](software.md#id6) + * [Columba](software.md#id8) + * [Ren TUI](software.md#ren-tui) + * [Chat](software.md#chat) * [Reticulum Relay Chat](software.md#reticulum-relay-chat) * [RetiBBS](software.md#retibbs) - * [RBrowser](software.md#rbrowser) + * [Voice & Telephony](software.md#voice-telephony) * [Reticulum Network Telephone](software.md#reticulum-network-telephone) + * [Partyline](software.md#partyline) * [LXST Phone](software.md#lxst-phone) - * [LXMFy](software.md#lxmfy) - * [LXMF Interactive Client](software.md#lxmf-interactive-client) + * [System Administration](software.md#system-administration) + * [Remote Shell](software.md#remote-shell) * [RNS FileSync](software.md#rns-filesync) + * [Utilities & Components](software.md#utilities-components) + * [Modem73](software.md#modem73) + * [LXMFy](software.md#lxmfy) * [Micron Parser JS](software.md#micron-parser-js) + * [Reticulated](software.md#reticulated) * [RNMon](software.md#rnmon) + * [Device Flashers](software.md#device-flashers) * [Protocols](software.md#protocols) * [LXMF](software.md#lxmf) - * [LXST](software.md#id16) + * [LXST](software.md#id30) * [RRC](software.md#rrc) * [Interface Modules & Connectivity Resources](software.md#interface-modules-connectivity-resources) * [Using Reticulum on Your System](using.md) @@ -270,6 +281,75 @@ to participate in the development of Reticulum itself. * [Filetransfer](examples.md#filetransfer) * [Custom Interfaces](examples.md#custom-interfaces) * [Reticulum License](license.md) +* [Brandolini’s Reference](brandolinis.md) + * [What The Reticulum License Is](brandolinis.md#what-the-reticulum-license-is) + * [Why This License Exists](brandolinis.md#why-this-license-exists) + * [On Freedom](brandolinis.md#on-freedom) + * [The Prediction, And What Happened](brandolinis.md#the-prediction-and-what-happened) + * [What This Means For Other Implementations](brandolinis.md#what-this-means-for-other-implementations) + * [Copyright & The Two Legal Layers](brandolinis.md#copyright-the-two-legal-layers) + * [The “Clean-Room” Delusion](brandolinis.md#the-clean-room-delusion) + * [Open Source Means Open Source](brandolinis.md#open-source-means-open-source) + * [What The Argument Is Actually Doing](brandolinis.md#what-the-argument-is-actually-doing) + * [Who Is Restricted By Which License?](brandolinis.md#who-is-restricted-by-which-license) + * [The Consequences Of The “Not Open Source” Claim](brandolinis.md#the-consequences-of-the-not-open-source-claim) + * [The Distribution Argument](brandolinis.md#the-distribution-argument) + * [On The Institutions, In Fairness](brandolinis.md#on-the-institutions-in-fairness) + * [What “Open” Means Positively](brandolinis.md#what-open-means-positively) + * [Assistance Versus Machine-Substitution](brandolinis.md#assistance-versus-machine-substitution) + * [False Dichotomy](brandolinis.md#false-dichotomy) + * [The Line](brandolinis.md#the-line) + * [What assistance looks like](brandolinis.md#what-assistance-looks-like) + * [What substitution looks like](brandolinis.md#what-substitution-looks-like) + * [Infrastructure Matters](brandolinis.md#infrastructure-matters) + * [The Fluency Trap](brandolinis.md#the-fluency-trap) + * [Disclosed Assistance Or Laundered Generation](brandolinis.md#disclosed-assistance-or-laundered-generation) + * [The License In This Context](brandolinis.md#the-license-in-this-context) + * [The General Principle](brandolinis.md#the-general-principle) + * [Void Grants: Legal Foundations of Machine-Generated Code](brandolinis.md#void-grants-legal-foundations-of-machine-generated-code) + * [I. The Foundational Statute: Translation Is Copying](brandolinis.md#i-the-foundational-statute-translation-is-copying) + * [II. Ideas Are Free, Expressions Protected](brandolinis.md#ii-ideas-are-free-expressions-protected) + * [III. Machine Output Has No Author](brandolinis.md#iii-machine-output-has-no-author) + * [IV. License Conditions Bound the Grant](brandolinis.md#iv-license-conditions-bound-the-grant) + * [V. The Void Grant](brandolinis.md#v-the-void-grant) + * [VI. Fair Use Does Not Rescue This Pattern](brandolinis.md#vi-fair-use-does-not-rescue-this-pattern) + * [Conclusion](brandolinis.md#conclusion) + * [Sources and Authorities](brandolinis.md#sources-and-authorities) + * [Evaluating a Reticulum Implementation](brandolinis.md#evaluating-a-reticulum-implementation) + * [The Intention Of This Guide](brandolinis.md#the-intention-of-this-guide) + * [Two Questions That Resolve Most Cases](brandolinis.md#two-questions-that-resolve-most-cases) + * [Other Signals To Look For](brandolinis.md#other-signals-to-look-for) + * [The Conformal Surface](brandolinis.md#the-conformal-surface) + * [Possible Verdicts](brandolinis.md#possible-verdicts) + * [These Standards Are Reasonable](brandolinis.md#these-standards-are-reasonable) + * [The Movement Of A Dozen](brandolinis.md#the-movement-of-a-dozen) + * [Presentation, Elongated](brandolinis.md#presentation-elongated) + * [Headcount](brandolinis.md#headcount) + * [Recycled Wine, Fermenting](brandolinis.md#recycled-wine-fermenting) + * [The Method of Madness](brandolinis.md#the-method-of-madness) + * [A Persistent, But Fragile Triad](brandolinis.md#a-persistent-but-fragile-triad) + * [What The Pattern Is Not](brandolinis.md#what-the-pattern-is-not) + * [Intent & Consequence](brandolinis.md#intent-consequence) + * [Recognition & Response](brandolinis.md#recognition-response) + * [Network Health & Coexistence](brandolinis.md#network-health-coexistence) + * [Substance Of The Networks](brandolinis.md#substance-of-the-networks) + * [Health Is A Property Of The Whole](brandolinis.md#health-is-a-property-of-the-whole) + * [A History Of What Works](brandolinis.md#a-history-of-what-works) + * [The Role Of The Individual](brandolinis.md#the-role-of-the-individual) + * [The Place Of New Implementations](brandolinis.md#the-place-of-new-implementations) + * [Expanding The Commons](brandolinis.md#expanding-the-commons) + * [Defence Of The Commons](brandolinis.md#defence-of-the-commons) + * [Addendum A: The Prns Case](brandolinis.md#addendum-a-the-prns-case) + * [Purpose & Scope](brandolinis.md#purpose-scope) + * [The Project In Brief](brandolinis.md#the-project-in-brief) + * [Question 1: Is this a clean implementation, or was it directly generated from the reference?](brandolinis.md#question-1-is-this-a-clean-implementation-or-was-it-directly-generated-from-the-reference) + * [Question 2: Who, or what, is the agent of the work?](brandolinis.md#question-2-who-or-what-is-the-agent-of-the-work) + * [The performance claims](brandolinis.md#the-performance-claims) + * [Overall Evaluation](brandolinis.md#overall-evaluation) + * [Licensing Analysis](brandolinis.md#licensing-analysis) + * [Consequences](brandolinis.md#consequences) + * [Verdict](brandolinis.md#verdict) + * [Dating](brandolinis.md#dating) * [API Reference](reference.md) * [`Reticulum`](reference.md#RNS.Reticulum) diff --git a/docs/markdown/reference.md b/docs/markdown/reference.md index a6d81c26..8c6c8668 100644 --- a/docs/markdown/reference.md +++ b/docs/markdown/reference.md @@ -860,7 +860,7 @@ statistics, you will be able to retrieve stats such as *RSSI*, *SNR* and physica #### `get_expected_rate()` * **Returns:** - The packet expected in-flight data rate of an established link. + The expected in-flight data rate of an established link. #### `get_mode()` diff --git a/docs/markdown/software.md b/docs/markdown/software.md index 26060e0c..024a5511 100644 --- a/docs/markdown/software.md +++ b/docs/markdown/software.md @@ -1,100 +1,99 @@ # Programs Using Reticulum -This chapter provides a non-exhaustive list of notable programs, systems and application-layer -protocols that have been built using Reticulum. +This chapter provides a non-exhaustive list of notable programs, systems and application-layer protocols that have been built using Reticulum. -These programs will let you get a feel for how Reticulum works. Most of them have been designed -to run well even over slow networks based on LoRa or packet radio, but all can also be used over fast -links, such as local WiFi, wired Ethernet, the Internet, or any combination. +Many different applications using Reticulum already exist, serving a wide variety of purposes from day-to-day communication and information sharing to systems administration and tackling advanced networking and communications challenges. -As such, it is easy to get started experimenting, without having to set up any radio -transceivers or infrastructure just to try it out. Launching the programs on separate -devices connected to the same WiFi network is enough to get started, and physical -radio interfaces can then be added later. +These programs will let you get a feel for how Reticulum works. Most of them have been designed to run well even over slow networks based on LoRa or packet radio, but all can also be used over fast links, such as local WiFi, wired Ethernet, the Internet, or any combination. -## Programs & Utilities +As such, it is easy to get started experimenting, without having to set up any radio transceivers or infrastructure just to try it out. Launching the programs on separate devices connected to the same WiFi network is enough to get started, and physical radio interfaces can then be added later. -Many different applications using Reticulum already exist, serving a wide variety of purposes -from day-to-day communication and information sharing to systems administration and tackling -advanced networking and communications challenges. +Development of Reticulum-based applications and systems is ongoing, so consider this list a non-exhaustive starting point of *some* of the options available. With a bit of searching, primarily over Reticulum itself, you will find many more interesting things. -Development of Reticulum-based applications and systems is ongoing, so consider this list -a non-exhaustive starting point of *some* of the options available. With a bit of searching, -primarily over Reticulum itself, you will find many more interesting things. +## Browsing & Publishing -### Remote Shell +In addition to the programs listed in this section, other Nomad Network clients include: -The [rnsh](https://github.com/acehoss/rnsh) program lets you establish fully interactive -remote shell sessions over Reticulum. It also allows you to pipe any program to or from a -remote system, and is similar to how `ssh` works. The `rnsh` program is very efficient, and -can facilitate fully interactive shell sessions, even over extremely low-bandwidth links, -such as LoRa or packet radio. - -In addition to the default, fully interactive terminal mode, -for extremely limited links, `rnsh` offers line-interactive mode, allowing you to interact -with remote systems, even when link throughput is counted in a few hundreds of bits per second. +- [MeshChatX](https://meshchatx.com/) +- [Columba](https://github.com/torlando-tech/columba/) ### Nomad Network -The terminal-based program [Nomad Network](https://github.com/markqvist/nomadnet) -provides a complete encrypted communications suite built with Reticulum. It features -encrypted messaging (both direct and delayed-delivery for offline users), file sharing, -and has a built-in text-browser and page server with support for dynamically rendered pages, -user authentication and more. +The terminal-based program [Nomad Network](https://github.com/markqvist/nomadnet) provides a complete encrypted communications suite built with Reticulum. -[![image](screenshots/nomadnet_3.png)](https://github.com/markqvist/nomadnet) +It features encrypted LXMF messaging (both direct and delayed-delivery for offline users), file sharing, and has a built-in text-browser and page server with support for dynamically rendered pages, user authentication and more. It also includes an RRC client and a suite of network utilities. -[Nomad Network](https://github.com/markqvist/nomadnet) is a user-facing client -for the messaging and information-sharing protocol LXMF. +### Ren Browser + +[Ren Browser](https://github.com/Quad4-Software/Ren-Browser) is a modern, standalone browser for Nomad Network using the [Reticulum-Go](https://github.com/Quad4-Software/Reticulum-Go) implementation. The project is actively being developed, and should be considered alpha level software, but much of the functionality is already working. If you want to help expanding the ecosystem, this is an excellent project to take a look at. + +Ren Browser is great example of an application aiming for true, seamless interoperability with the existing software ecosystem. It can operate fully standalone using it’s own embedded [Go implementation](https://github.com/Quad4-Software/Reticulum-Go) of Reticulum, or seamlessly utilise a shared RNS instance already running on the system. ### RNS Page Node -[RNS Page Node](https://git.quad4.io/RNS-Things/rns-page-node) is a simple way to serve pages and files to any other Nomad Network compatible client. Drop-in replacement for NomadNet nodes that primarily serve pages and files. +[RNS Page Node](https://github.com/Quad4-Software/rns-page-node) is a simple way to serve pages and files to any other Nomad Network compatible client. Drop-in replacement for NomadNet nodes that primarily serve pages and files. ### Retipedia -You can host the entirity of Wikipedia (or any `.zim`) file to other Nomad Network clients using [Retipedia](https://github.com/RFnexus/Retipedia). +You can host the entirity of Wikipedia, StackExchange or any other `.zim` file, to Nomad Network clients using [Retipedia](https://github.com/RFnexus/Retipedia). + +### Git Over Reticulum + +The included [rngit](git.md#git-main) system provides a fully distributed solution for managing, hosting, collaborating on and interacting with Git repositories over Reticulum. + +## Messaging & Voice ### Sideband -If you would rather use an LXMF client with a graphical user interface, you can take -a look at [Sideband](https://unsigned.io/sideband), which is available for Android, -Linux, macOS and Windows. Sideband is an advanced LXMF and LXST client, and a multi-purpose Reticulum -utility, with features and functionality targeted at advanced users. +[Sideband](https://github.com/markqvist/Sideband) is a technical LXMF and LXST client, for Android, Linux, macOS and Windows. It also serves as a multi-purpose Reticulum utility, with features and functionality targeted at advanced users. -Sideband allows you to communicate with other people or LXMF-compatible -systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, Encrypted QR -Paper Messages, or anything else Reticulum supports. +Sideband allows you to communicate with other people or LXMF-compatible systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, Encrypted QR Paper Messages, or anything else Reticulum supports. -It also interoperates with all other LXMF clients, and provides advanced features such as voice messaging, -real-time voice calls, file attachments, private telemetry sharing, and a full -plugin system for expandability. +It interoperates with all other LXMF clients, and provides advanced features such as PTT and voice messaging, real-time voice calls, file attachments, private telemetry sharing, and a full plugin system for expandability. ### MeshChatX -A [Reticulum MeshChat fork from the future](https://git.quad4.io/RNS-Things/MeshChatX), with the goal of providing everything you need for Reticulum, LXMF, and LXST in one beautiful and feature-rich application. This project is separate from the original [Reticulum MeshChat](https://github.com/liamcottle/reticulum-meshchat) project, and is not affiliated with the original project, but is a much more up-to-date, comprehensive and well-maintained fork. +[MeshChatX](https://meshchatx.com/) is an all-in-one Reticulum client with messaging, calling, and a NomadNet browser, providing everything you need for Reticulum, LXMF, and LXST in one beautiful and feature-rich application. -Features include full LXST support, custom voicemail, phonebook, contact sharing, and ringtone support, multi-identity handling, modern UI/UX, offline documentation, expanded tools, page archiving, integrated maps, telemetry and improved application security. +Features include full LXST support, custom voicemail, phonebook, contact sharing, ringtone support, multi-identity handling, modern UI/UX, offline documentation, expanded tools, page archiving, integrated maps, telemetry and improved application security. + +### Columba + +[Columba](https://github.com/torlando-tech/columba/) is a simple and familiar LXMF messaging app Android, built with a native Android interface and Material Design 3. It also includes LXST voice call functionality, and a mobile Nomad Network page browser. + +### Ren TUI + +[Ren TUI](https://github.com/Quad4-Software/Ren-TUI) is an early prototype terminal LXMF client for Reticulum built with Odin on librns (Reticulum-Go). It aims for NomadNet-like messaging/browsing without urwid or ncurses. + +## Chat ### Reticulum Relay Chat [Reticulum Relay Chat](https://rrc.kc1awv.net/) is a live chat system built on top of the Reticulum Network Stack. It exists to let people talk to each other in real time over Reticulum without dragging in message databases, synchronization engines, or architectural commitments they did not ask for. -The [rrcd](https://github.com/kc1awv/rrcd) program provides a functional, reference RRC hub-server daemon implementation. RRC user clients include [rrc-gui](https://github.com/kc1awv/rrc-gui) and [rrc-web](https://github.com/kc1awv/rrc-web). - RRC is closer in spirit to IRC than to modern “everything platforms.” You connect, you join a room, you talk, and then you leave. If you were present, you saw the conversation. If you were not, the conversation did not wait for you. This is not an accident. This is the entire design. +The [rrcd](https://github.com/kc1awv/rrcd) program provides a functional, reference RRC hub-server daemon implementation. RRC user clients include: + +- [Nomad Network](https://github.com/markqvist/NomadNet/) +- [MeshChatX](https://meshchatx.com/) +- [Eridanus](https://github.com/torlando-tech/eridanus) +- [rrc-gui](https://github.com/kc1awv/rrc-gui) +- [rrc-web](https://github.com/kc1awv/rrc-web) + ### RetiBBS -[RetiBBS](https://github.com/kc1awv/RetiBBS) is a bulletin board system implementation for Reticulum networks. +[RetiBBS](https://github.com/kc1awv/RetiBBS) is an old-school bulletin board system implementation for Reticulum networks. RetiBBS allows users to communicate through message boards in a secure manner. -### RBrowser +## Voice & Telephony -The [rBrowser](https://github.com/fr33n0w/rBrowser) program is a cross-platform, standalone, web-based browser for exploring NomadNetwork Nodes over Reticulum Network. It automatically discovers NomadNet nodes through network announces and provides a user-friendly interface for browsing distributed content with Micron markup support. +In addition to the programs listed in this section, other LXST voice clients include: -Includes useful features like automatic listening for announce, adding nodes to favorites, browsing and rendering any kind of NomadNet links, downloading files from remote nodes, a unique local NomadNet Search Engine and more. +- [Sideband](https://github.com/markqvist/Sideband) +- [MeshChatX](https://meshchatx.com/) +- [Columba](https://github.com/torlando-tech/columba/) ### Reticulum Network Telephone @@ -102,32 +101,67 @@ The `rnphone` program, included as part of the [LXST](https://github.com/markqvi It supports interfacing directly with hardware peripherals such as GPIO keypads and LCD displays, providing a modular system for building secure hardware telephones. +### Partyline + +[Partyline](https://github.com/RFnexus/partyline) is a group voice application for Reticulum, built on [LXST](https://github.com/markqvist/LXST), inspired by [Mumble](https://github.com/mumble-voip/mumble). + +It provides both realtime group voice over any Reticulum transport capable of >6 kilobits per second, LXST dial-in support, listen-only music/broadcasting rooms, and many other useful functions. + ### LXST Phone -The [LXST Phone](https://github.com/kc1awv/lxst_phone) program is a cross-platform desktop application for performing LXST voice calls over Reticulum. +The [LXST Phone](https://github.com/kc1awv/lxst_phone) program is a cross-platform desktop application for performing LXST voice calls over Reticulum. It supports various advanced features such as SAS verification, peer blocking, rate limiting, encrypted call history storage and contact management. -It supports various advanced features such as SAS verification, peer blocking, rate limiting, encrypted call history storage and contact management. +## System Administration -### LXMFy +### Remote Shell -[LXMFy](https://lxmfy.quad4.io/) is a comprehensive and advanced bot creation framework for LXMF, that allows building any kind of automation or bot system running over LXMF and Reticulum. [Bot implementations exist](https://github.com/lxmfy/awesome-lxmfy-bots) for Home Assistant control, LLM integrations, and various other purposes. +The included [rnsh](using.md#using-rnsh) program lets you establish fully interactive +remote shell sessions over Reticulum. It also allows you to pipe any program to or from a +remote system, and is similar to how `ssh` works. The `rnsh` program is very efficient, and +can facilitate fully interactive shell sessions, even over extremely low-bandwidth links, +such as LoRa or packet radio. -### LXMF Interactive Client - -[LXMF Interactive Client](https://github.com/fr33n0w/lxmf-cli) is a feature-rich, terminal-based LXMF messaging client with many advanced features and an extensible plugin architecture. +In addition to the default, fully interactive terminal mode, for extremely limited links, +`rnsh` offers line-interactive mode, allowing you to interact with remote systems, even +when link throughput is counted in a few hundreds of bits per second. ### RNS FileSync -The [RNS FileSync](https://git.quad4.io/RNS-Things/RNS-Filesync) program enables automatic file synchronization between devices without requiring central servers, internet connectivity, or cloud services. It works over any network medium supported by Reticulum, including radio, LoRa, WiFi, or the internet, making it ideal for off-grid, privacy-focused, and resilient file sharing. +The [RNS FileSync](https://github.com/Quad4-Software/RNS-Filesync) program enables automatic file synchronization between devices without requiring central servers, internet connectivity, or cloud services. It works over any network medium supported by Reticulum, including radio, LoRa, WiFi, or the internet, making it ideal for off-grid, privacy-focused, and resilient file sharing. + +## Utilities & Components + +### Modem73 + +[MODEM73](https://github.com/RFnexus/modem73) and its companion [Modem73Interface](https://github.com/RFnexus/modem73interface) is an open source software modem that works with any HF, VHF, or UHF radio capable of 2400 Hz of bandwidth. All you need is a sound card and audio cable for your radio. + +### LXMFy + +[LXMFy](https://lxmfy.quad4.io/) is a comprehensive and advanced bot creation framework for LXMF, that allows building any kind of automation or bot system running over LXMF and Reticulum. [Bot implementations exist](https://lxmfy.quad4.io/latest/creating-bots/) for Home Assistant control, LLM integrations, and various other purposes. ### Micron Parser JS [Micron Parser JS](https://github.com/RFnexus/micron-parser-js) is the JavaScript-based parser for the Micron markup language, that most web-based Nomad Network browsers use. If you want to make utilities or tools that display Micron pages, this library is essential. +### Reticulated + +[Reticulated](https://github.com/RFnexus/Reticulated) is a Reticulum Network simulator that spawns live, interactive Reticulum instances controllable from a node-based Web UI. + +You can create networks of any topology and set bitrate, MTU, and configure path loss and propagation behavior. It provides a top-down view to a live network. You can connect any Reticulum application to the simulated network. It also has built in utilities like a basic LXMF chat function and Resource transfer included. + ### RNMon [RNMon](https://github.com/lbatalha/rnmon) is a monitoring daemon designed to monitor the status of multiple RNS applications and push the metrics to an InfluxDB instance over the influx line protocol. +## Device Flashers + +In addition to the included command-line `rnodeconf` flasher, several community-provided RNode device flashers exist: + +- [RNS Moscow](https://flasher.rns.moscow/) +- [Aetherlab](https://flasher.aetherlab.org/) + +Several programs, such as [Sideband](https://github.com/markqvist/Sideband) and [MeshChatX](https://meshchatx.com/) also include built-in device flashers that can be used fully offline. + ## Protocols A number of standard protocols have emerged through real-world usage and testing in the Reticulum community. While you may sometimes want to use completely custom protocols and implementations when writing Reticulum-based software, using these protocols provides application developers with an easy way to implement advanced functionality quickly and effortlessly. Using them also ensures compatibility and interoperability between many different client applications, creating an open communications ecosystem where users are free to choose the applications that suit their needs, while remaining connected to everyone else. @@ -154,8 +188,8 @@ RRC is intentionally simple. It does not pretend to be email, a mailbox, or a di This section provides a list of various community-provided interface modules, guides and resources for creating Reticulum networks over special or challenging mediums. -* Custom interface module for running [RNS over HTTP](https://git.quad4.io/RNS-Things/RNS-over-HTTP) +* [Modem73](https://github.com/RFnexus/modem73) is an efficient software modem that can be used with Reticulum +* Custom interface module for running [RNS over HTTP](https://github.com/Quad4-Software/RNS-over-HTTP) * Guide for running [Reticulum over ICMP](https://github.com/matvik22000/rns-over-icmp) using `PipeInterface` * Guide for running [Reticulum over DNS](https://github.com/markqvist/Reticulum/discussions/1002) with Iodine -* Guide for running [Reticulum over HF radio](https://github.com/RFnexus/reticulum-over-hf) -* [Modem73](https://github.com/RFnexus/modem73) is a KISS TNC OFDM modem frontend that can be used with Reticulum \ No newline at end of file +* Guide for running [Reticulum over HF radio](https://github.com/RFnexus/reticulum-over-hf) \ No newline at end of file diff --git a/docs/markdown/support.md b/docs/markdown/support.md index 69a9aefe..46ec7440 100644 --- a/docs/markdown/support.md +++ b/docs/markdown/support.md @@ -24,9 +24,6 @@ Ko-Fi: https://ko-fi.com/markqvist ``` -Are certain features in the development roadmap are important to you or your -organisation? Make them a reality quickly by sponsoring their implementation. - ## Provide Feedback Feedback on the usage, functioning and potential dysfunctioning of any and diff --git a/docs/markdown/using.md b/docs/markdown/using.md index 7ab5c9f5..f930caf8 100644 --- a/docs/markdown/using.md +++ b/docs/markdown/using.md @@ -256,8 +256,7 @@ You can easily add `rnsd` as an always-on service by [configuring a service](#us ### The rnstatus Utility -Using the `rnstatus` utility, you can view the status of configured Reticulum -interfaces, similar to the `ifconfig` program. +Using the `rnstatus` utility, you can view the status of and control configured Reticulum interfaces, similar to the `ifconfig` program. **Usage Examples** @@ -331,6 +330,9 @@ options: -h, --help show this help message and exit --config CONFIG path to alternative Reticulum config directory --version show program's version number and exit + --attach name Attach interface by name + --detach name Detach interface by name + --reload name Reload interface by name -a, --all show all interfaces -A, --announce-stats show announce stats -P, --pr-stats show path request stats @@ -348,6 +350,8 @@ options: -w seconds timeout before giving up on remote queries -d, --discovered list discovered interfaces -D show details and config entries for discovered interfaces + --show-stale show stale discovery entries + --show-unknown show discovery entries without version info -m, --monitor continuously monitor status -I, --monitor-interval seconds refresh interval for monitor mode (default: 1) @@ -674,7 +678,7 @@ For the full documentation on the rngit system, see the [Git Over Reticulum](git The `rnx` utility is a basic remote command execution program. It allows you to execute commands on remote systems over Reticulum, and to view returned command output. For a fully interactive remote shell solution, be sure to also take a look -at the [rnsh](https://github.com/acehoss/rnsh) program. +at the [rnsh](#using-rnsh) program. **Usage Examples** @@ -1183,6 +1187,7 @@ For more fine-grained control over how discovered interfaces are auto-connected, * The `autoconnect_interface_mode` options specifies which mode discovered interfaces should be created with when auto-connecting. * The `autoconnect_announces_to_internal` option allows you to specify that auto-connected interfaces should propagate announces to `internal` mode interfaces, even if the auto-connected interface’s mode would normally not allow for this. +* The `autoconnect_unverified_implementations` option will allow the interface discovery system to auto-connect to *any* announced interface, even those coming from unverified, experimental or potentially broken implementations. Be very careful with this option. ## Remote Management diff --git a/docs/source/brandolinis.rst b/docs/source/brandolinis.rst new file mode 100644 index 00000000..334dc662 --- /dev/null +++ b/docs/source/brandolinis.rst @@ -0,0 +1,1625 @@ +.. _brandolinis-main: + +Brandolini's Reference +====================== + + | *A little learning is a dang’rous thing;* + | *Drink deep, or taste not the Pierian spring.* + | *There shallow draughts intoxicate the brain,* + | *And drinking largely sobers us again.* + | + | - Alexander Pope, 1711 + +This chapter serves as a helpful reference for developers, users and community members living in an Age of Bullshit Manufacture equivalent to the Cambrian Explosion. + +As we are surely only at the on-ramp of this trajectory, the chapter will continue to evolve, expand and be updated based on community feedback as events occur. + +.. _brandolinis-what-the-license-is: + +What The Reticulum License Is +----------------------------- + +*To understand the legal reality relating to this section, see* :ref:`Void Grants`. + +The :ref:`Reticulum License` is the license under which RNS, the Reticulum reference implementation, has been published since **April 15, 2025**\ , in versioning effective from **0.9.4** and every release since. In practical terms, it covers all of "modern Reticulum": The current wire format, the cryptographic machinery as it exists today (including the AES-256-based link encryption, ratchets, et cetera), and all protocol additions that distinguish the modern implementation from the earliest pre-1.0.0 beta formats. If an implementation speaks today's Reticulum protocol, it is, in all relevant respects, built on Reticulum-licensed work. + +The license is a permissive license. It grants the full range of rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, free of charge; subject to three conditions, which are reproduced here verbatim: + +.. + + * + The Software shall not be used in any kind of system which includes amongst its + functions the ability to purposefully do harm to human beings. + + * + The Software shall not be used, directly or indirectly, in the creation of an artificial + intelligence, machine learning or language model training dataset, including but not + limited to any use that contributes to the training or development of such a model or + algorithm. + + * + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + +.. _brandolinis-why-the-license-exists: + +Why This License Exists +^^^^^^^^^^^^^^^^^^^^^^^ + +Reticulum was not moved to a custom license casually or quickly. It was licensed under the MIT license for the greater part of its existence, and that served well for a long time. The change came when it became clear that no existing license expressed what the project needed, and that the two most commonly proposed alternatives would either say the wrong thing or say nothing useful at all. Three factors had primary influence on the situation: + +**The harm problem** + +Reticulum is a tool that was built, deliberately and at great cost, to empower people; to make communication something you own rather than something you are temporarily granted. It has also been, at various times, exactly what certain kinds of organisations would like to use to control people. This is the duality of any powerful tool. A permissive license could not, and cannot, say anything about that; MIT is silent on the question of whether the software may be used to build systems designed to harm human beings. The Reticulum License is not silent. It does not pretend that a license can stop an individual madman; it does assert, however, plainly and in enforceable terms, that corporations and organisations integrated into the legal system cannot consume this software for harm and then claim they never knew. The line is drawn by the creators of the tool, not by an external authority, and it is drawn deliberately. This is covered in more depth in the discussion of the ethics of the tool in the *Zen of Reticulum*. + +**The appropriation problem** + +The second factor was the machine-learning appropriation of the open-source commons. By 2025 that was no longer hypothetical: The commons was already being systematically ingested by corporate training pipelines, and the code, words, and creativity of the people who built it were being converted into synthetic systems designed to replace them. The license responds to this with an explicit condition: The software shall not be used in the creation of an AI, machine-learning, or language-model training dataset, nor in any use that contributes to the training or development of such a model or algorithm. + +It is important to understand what this condition does and does not do, which matters for what follows in this chapter. **The AI-training condition is not the legal basis for protecting the code from machine copying**. That protection *already exists*\ , in the oldest and most well-tested form of copyright law, and it applies regardless of any license (see :ref:`Copyright & The Two Legal Layers`). + +The AI-training condition addresses something *additional*\ : the appropriation of the code *into the models themselves*\ ; the ingestion of human-made work as raw material for a synthetic replacement, and the use of that ingestion to fabricate "prior work" minefields, patent-troll material, and a wall of slop meant to bury and devalue the actual ecosystem. That danger was foreseeable; the licensing decision was made with full awareness of it. The events of 2026 have since demonstrated, in public and in detail, that the concern was not theoretical. + +**The sustainability problem** + +Reticulum has been developed and maintained for over a decade by a single person, supported by a small group of contributors and network-building users, without corporate backing, without VC funding, through several serious attempts at commercialization and takeover from both the corporate and the ideological side. The license is part of what makes that sustainable, and possible at all. + +It ensures that the specific, painstaking labor of the reference implementation cannot be hijacked to undermine the intent of the project, while leaving the protocol itself, the mathematical rules of how Reticulum works, dedicated to the public domain, where it belongs to humanity and can never be owned. Anyone can implement the protocol, provided they themselves invest the *actual* work and effort. What the license protects is the work, and the intent embodied in it. + +.. _brandolinis-on-freedom: + +On Freedom +^^^^^^^^^^ + +The most persistent mischaracterisation of the Reticulum License is that it is "more restrictive" than the licenses it replaced or than the GPL family. This is backwards, and I'll state the comparison plainly, because the confusion is the foundation of a great deal of deliberately manufactured controversy examined later in this chapter. + +The GPL and AGPL are constructed around a single, self-referential axiom: that "free" is *defined by the terms of the license itself*\ , and that any use falling outside those terms is not free. In practice, this means the GPL restricts the freedom of **everyone** - you may not write, distribute, link, or (in some cases) even communicate with GPL-covered software without the entire arrangement being pulled under the same terms, which the licensor then controls. The restriction applies to 100% of users, including the ones building purely constructive things. + +The Reticulum License restricts the freedom of almost nobody. Its restrictions apply only to: + +* Those who wish to use the software in systems that purposefully harm human beings, and +* Those who wish to ingest the software into AI training pipelines. + +That is a restriction on a vanishingly small fraction of would-be users - the 0.0000001% - and it is a restriction they can characterise however they like, forever. The bickering is itself a signal that the licensing decision hit exactly the right target. + +Everyone else retains the full breadth of use, modification, distribution, and sale, with none of the viral encumbrance of copyleft. + +Both licenses contain moral axioms. The difference is that the Reticulum License states its axioms out loud: + +* *Intentionally restricting the way that millions of people use and build upon a foundational + communications technology* - **The mechanism of copyleft** +* *Intentionally restricting a small number of organisations from using the technology to + violently harm human beings* - **The mechanism of the Reticulum License** + +Which of these is more free? The answer is not a matter of committee approval. It is a matter of what the word "free" means to the people *whose freedom is at stake*. The question of whether "open source" requires the blessing of a particular licensing orthodoxy is examined in :ref:`Open Source Means Open Source`. + +.. _brandolinis-prediction: + +The Prediction, And What Happened +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When the license change was made and publicly discussed in 2025, the following was said, in public, about the machine-learning threat: + +.. + + A generative system could be trained on the Reticulum codebase, and for extremely low cost + be set to work spewing out millions of source repositories for all kinds of ridiculous + "Reticulum-based programs". This is already happening. You can find several examples of this + on GitHub already. … the point of this kind of trolling is to establish as wide a base for + "prior work" as possible. By doing that, a patent troll or IP abuser can create an immense + minefield for real developers. + + +This was written when the phenomenon was just beginning. It was not a guess; it was a description of a mechanism already in motion, in the specific context of Reticulum, by people who had already begun to appear around the project. + +Less than a year and a half later, the prediction has now been demonstrated, in public, exhaustively and to the letter. There are now roughly a dozen machine-generated "Reticulum implementations" of the same shape: fluent, marketing-heavy, some without attribution, and - in several cases - actively harmful to the network. The :ref:`Prns case` is an example documented in this chapter. The pattern that produced it (and the people, mechanisms, and the recycling of falsehoods behind the *wider* phenomenon) is examined in :ref:`A Movement Of A Dozen`. + +The license was written, in part, so that when this happened, the community would not be defenceless. + +.. _brandolinis-means-for-other-implementations: + +What This Means For Other Implementations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Two simple things must be kept separate: + +#. + **The protocol is public domain.** The mathematical rules of Reticulum - addresses, + signatures, routing, the wire format as an idea - belong to humanity. A *genuine* clean-room + implementation of the protocol, written by human beings who reasoned it out themselves, is + free and welcome, and owes nothing to the Reticulum License. Nothing in this chapter is an + argument against implementing the protocol. On the contrary: More good implementations, + honestly made, are good for the network. + +#. + **The implementation is licensed.** Copying the reference implementation - by machine or + by silk-screen press - and modifying and redistributing the result, is + exercising rights granted by the license, and is therefore subject to its conditions: The attribution + notice, the harm condition, the AI-training condition. A copy that does not follow those + conditions is **not** licensed, and it is not "open source in spirit"; it is an unauthorized + derivative work, and therefore a copyright violation. + +The distinction is the same one the license itself makes, and it must be held firmly: An implementation that *speaks* Reticulum is exercising the public domain protocol, **if** it was truly created independently. An implementation that was *generated from* RNS, reproduced by a copy process, is a derivative of licensed work. + +.. _brandolinis-copyright-and-layers: + +Copyright & The Two Legal Layers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The exact legal structure is frequently muddied in public discussion; and in several cases deliberately. + +**Layer A - Copyright (license-independent)** + +Copyright does not depend on any license. A primarily machine-generated copy of a copyrighted work - a copy not accompanied by demonstrable, substantial, new human creative input - is a derivative work over which the copier holds no copyright whatsoever, and the reproduction of which, without the original author's permission, is an infringement of the original author's copyright. This is standard, well-tested law, and it applies with equal force under the MIT license, the GPL, or any other license, because it is not about the license at all; it is about who created what. A process that copies the reference implementation into a machine, produces a transformed derivative, and then claims "Copyright, [name of the process operator]" - with no human able to account for the creative decisions in the result - **is not** asserting a valid copyright over the result. They are openly asserting the absence of one, and reproducing someone else's work without authorisation. This is probably the cleanest cut copyright violation one could imagine. + +**Layer B - License Conditions (Reticulum License specific)** + +Where a copy *is* a licensed derivative, the conditions of the Reticulum License apply: The copyright notice and permission notice must be included in all copies and substantial portions; the harm condition must be honoured; the AI-training condition must be honoured. A derivative that follows none of these is unlicensed *a second way over*. + +The two layers are often intentionally confused in public discussion - the AI-training condition is waved around as if the entire question of machine copying rested on it, when in fact machine copying of copyrighted work is a copyright violation that would exist even under the most permissive license ever written. The purpose of keeping the layers separate is not rhetorical flourish; it is that Layer A is old, settled law, and does not rely on any novel legal theory, while Layer B is specific to this license. Both matter. Neither is a substitute for the other. + +Layer B is the required mechanism for closing the loophole where the work is *first* ingested during model training into the weights of a model itself, which would make any resulting violations almost impossible to detect and enforce. + +.. _brandolinis-cleanroom-delusion: + +The "Clean-Room" Delusion +^^^^^^^^^^^^^^^^^^^^^^^^^ + +I regularly receive mail or LXMF messages from people who proudly and happily proclaim that they have created a "clean-room" implementation of one of the software systems I maintain; RNS, Sideband, LXMF or others. The declaration is delivered with the flat certainty of someone who believes they have found the legal lock-pick that settles everything at once: Their production is independent, uncontaminated, and therefore free of any obligation to the work they copied, its license, or its author. The proclamation usually concludes with a request for blessing, or at least acknowledgment. The proclamation is, usually, also generated by an LLM. + +This is a delusion, and I'll cut through it surgically. The word they here invoke as magic is attempting to do a great deal of work it was never able to bear. + +**What a clean room actually was** + +The legal "clean room" is not folklore, incantation, witchcraft or a claim a person gets to make about their own output. It is a very specific, institutionalized procedure that grew out of the hardware and software litigations of the 1980s, and it existed for exactly one purpose: **Convincingly proving the absence of copying in a court of law**. + +The canonical case was Phoenix Technologies and its 1984 reimplementation of the IBM PC BIOS. IBM's BIOS was copyrighted, which meant that the entire PC-compatible industry depended on being able to show that a compatible BIOS had been written independently, and not from IBM's code. Phoenix's answer was a physical and procedural firewall: + +* One team, the "dirty room", read the original code and produced written *functional specifications*\ : descriptions of what the BIOS did, not how IBM's code did it. +* A second team, the "clean room", consisted of engineers who had *never seen the original code at all*\ , and they wrote the new BIOS from those specifications alone. + +This obsessively documented, legally attested separation was not a preference or a willy-nilly show for a kindergarten; it was the entire legal point, and it had to be *solid*. If even one clean-room engineer had *glanced* at IBM's code, the clone would have been contaminated, and the defense would shatter. + +The other landmark case was *Computer Associates v. Altai* (1992), in which Altai had copied CA's scheduler code into its own product, and (upon being caught) hired outside counsel to run a genuine clean-room procedure: A programmer with no exposure to the original was brought in to rewrite the infringing modules from functional specifications prepared by the team that had seen the code. The court credited the good-faith effort precisely because it was done, as the carefully documented record showed, to the letter of the procedure. + +Bear in mind what this procedure entailed in practice, because this is the part the modern claimants never seem to have even *heard* of: Physical separation of teams, legal counsel managing the process, signed and notarised declarations of non-exposure, controlled specification documents that described *behaviour* and never *code*, months of work, and testing against the specification - not against the original, which the implementers were forbidden to consult. + +The people on the clean-room side of the wall did not just *claim* they had not read the code. Their non-exposure was institutionally guaranteed, obsessively documented, and legally attestable through every fart and sneeze of the process, because the entire point was that a court - hostile, adversarial, and entitled to discovery - would believe it. + +*That* is the process. "Clean-room implementation" is the name of a *certified procedure for proving independent authorship*. It is not a mood, a marketing label, or a property a person gets to declare about their own work. + +**The moronic inversion** + +Now consider what is actually being described when someone says: *"I created a clean-room implementation of Reticulum by feeding the source code into a machine."* + +That sentence is the opposite of a clean room. Feeding a copyrighted work into a machine so that it reproduces and transforms the work is **the definition of copying**\ , and a clean room is the one procedure whose entire purpose is the demonstrated *absence* of copying. This process cannot demonstrate the absence of copying, because the process is *composed of* copying. The cleanest possible room has been replaced by the dirtiest possible room, and the dirt has been installed as the base feature. What these claimants have actually performed is a photocopy with extra steps, and the extra steps, far from cleaning anything, are simply steps that forge a certificate they believe the output has earned. + +**Why the word is deployed** + +The word "clean-room" is deployed because it sounds like what the speaker wishes were true. It carries the accumulated legal prestige of the 1980s and 1990s - the BIOS clones, the Altai credit - and it sounds like a certificate already issued: *Independent, original, unencumbered*\ , the work of a person who owes nothing. The claimants want that halo without the procedure: No law firm, no physical separation, no written specifications, no signed declarations, no months of process - just a laptop, a loop, and the word "clean-room" typed into a README. The word must do the work of the process it replaces, and the delusional replacement is the entire point. + +**The irony runs deep** + +The Reticulum protocol is public domain. Any human being can implement it - from the mathematics, from the documentation, from their own reasoning - and owe nothing whatsoever to the license, to the reference implementation, or to me. + +An honestly written implementation needs no incantations, no legal theater, and no special vocabulary; it simply *is* what it claims. It's plain for everyone to see. **It's also plain for everyone to see when you're faking it**. The people who reach for the word "clean-room" are, without exception, the people who need it to create a fantasy - and the people who need that are precisely the people who cannot have it. If what you wrote were genuinely independent work on the public-domain protocol, you would not need to call it anything. The word is not a seal of independence. In this context it is a confession of copying, filed by the copier, in the confident belief that it says the opposite. + +.. _brandolinis-opensource: + +Open Source Means Open Source +----------------------------- + +An objection regarding the "open source status" of RNS appears occasionally in variations, but always reduces to the same syllogism: + + +#. "Open source" means *licensed under one of the licenses approved by the Open Source + Initiative (or, in other variants, compatible with GPL orthodoxy)*. +#. The Reticulum License is not on that list. +#. Therefore Reticulum is not open source, and anything built on it is illegitimate. + +The entire argument rests on the first premise, and the first premise is false. + +Open source is not a certification conferred by a committee. It is a description of a fact: The source code is available, and the rights to use, copy, modify, merge, publish, distribute, sublicense, and sell it are granted to everyone, free of charge. + +The Reticulum License does all of those things. It is, in every substantive respect that concerns the person who wants to use, study, modify, or build upon the software, **an open license**. What it adds - and what disqualifies it in the eyes of the orthodoxy - is two conditions on *who may do what with the original work*\ , not on what the *user* is allowed to do with it. + +The definition being wielded against Reticulum is not even a young one. It is, in essence, the Debian Free Software Guidelines written in 1997, adopted by the OSI in 1998, and treated ever since by certain people as if it had descended from a mountain on tablets. It is an approach that is close to three decades old. Being old is not itself a flaw - but being old is also not a proof of correctness, and the suggestion that the meaning of a word like "open" was settled for all time by a committee in the 1990s, and may never be revisited, is not a position rooted in reason. It is rooted in institutional inertia dressed as principle, maintained by those whose ideologies it serves. + +.. _brandolinis-what-the-argument-is-doing: + +What The Argument Is Actually Doing +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +I would like to go into some detail about the rhetorical mechanism, because it is roughly the same mechanism that powers the rest of the campaign described later in this chapter. + +The orthodoxy's argument is self-referential: *"open source means what we say it means, because we are the ones who define it."* When the Reticulum License is measured against that definition and found wanting, the conclusion is presented as a property of Reticulum - when in fact it is *a property of the definition*. The definition is treated as neutral and authoritative - as some base fact of raw cosmology - and the license is treated as deviant. But the definition is no more neutral than the license is. It encodes a moral position, and that moral position is exactly the one that this project declines to take. + +Consider what the orthodoxy's definition requires, in the case at hand. The OSI-based definition contains, in its ancestry, the Debian Free Software Guideline of "No discrimination against fields of endeavor": The software must not restrict who may use it or for what purpose. Taken to its logical end, this means that open source, properly "certified", must be equally available to those who build hospitals and those who build weapons, those who connect people and those who control them, those who create and those who ingest and replace. + +The orthodoxy presents this as neutrality. It is not neutrality; it is a moral position - one that says, in effect, that *harming human beings is a field of endeavor like any other, and software must not discriminate against it*. + +The Reticulum License takes a different position, and it has the honesty to state it in the license text: this software is for life, not for death; it is for people, not for the systems that would replace them. That is not a restriction on openness, nor on freedom. It is a restriction on *who may consume the work*\ , and it is a restriction the orthodoxy's definition cannot express - which is why the orthodoxy must always attack the license as "not open source" rather than engage with what it actually does. + +.. _brandolinis-who-is-restricted: + +Who Is Restricted By Which License? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The arithmetic is simple, so let's do it out loud, because the orthodoxy's framing inverts it every time. + +The GPL family imposes its conditions on **everyone**\ : You may not distribute, link, or - in the AGPL case - even *communicate with* GPL-covered software without your own work being pulled under the same terms. "Free" in this system is defined (self-referentially) *by the license's own terms*\ ; everything outside those terms is, by definition, unfree. The restriction applies to 100% of users. It applies to the hospital, the mesh community, the school, and the hobbyist with the same force it applies to anyone else. That is not freedom for everyone; it is a *specific moral architecture applied to everyone*\ , presented *as if it were the absence of one*. + +The Reticulum License imposes its conditions on a fraction of would-be users so small as to be practically unmeasurable: + +* Those whose intended use is to build systems that purposefully harm human beings, and +* Those whose intended use is to ingest the work into AI training pipelines. + +That is the entire list. Everyone else - the overwhelming majority, the community, the developers, the users, the downstream projects - receives the full, unrestricted rights to use, copy, modify, merge, publish, distribute, sublicense, and sell the software, with none of the viral encumbrance of copyleft. + +So when the claim is made that the Reticulum License "is more restrictive" than the GPL, the claim is not merely wrong; it is the exact inverse of the truth. The GPL restricts the freedom of everyone, in the name of a specific ideology. + +The Reticulum License restricts the freedom of the harm-doer and the appropriator, and leaves everyone else free. The two approaches do not differ in whether they contain moral axioms - **all licenses do**. They differ in whether the axioms are stated openly, and in *whose* freedom they restrict. + +.. _brandolinis-consequences-not-open: + +The Consequences Of The "Not Open Source" Claim +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This would be a footnote debate if the mischaracterisation had no practical consequences. It has very large ones, and therefore this section exists. + +The claim that "Reticulum is not open source" is the foundation of the takeover narrative it so often accompanies. The sequence is always the same: + +* First, declare the reference implementation illegitimate ("not really open source", "owned by one man", "not a real community project") +* Second, conclude that it is therefore acceptable - even necessary - to replace it. +* Third, present the replacement, which is (conveniently) often the speaker's own machine-generated clone, as the legitimate heir. + +This is not speculation about motives; it is the documented structure of the campaign examined in :ref:`A Movement Of A Dozen`. + +The "not open source" claim is the legal-ideological battering ram of that campaign. It is recycled, in article after article, in forum after forum, because it works on people who assume that a committee's definition is the same thing as the truth. + +It is also worth stating the other obvious fact: None of these critics have ever shown that the Reticulum License restricts *them*. They do not build weapons. They are not training models on the codebase. They are free, in every practical sense, to use Reticulum exactly as they would under MIT or GPL. Their objection is not to a restriction on themselves; it is to the *mere existence* of a license that states a moral position they disagree with, or which they can use as leverage for a different goal entirely, and to the institutional fact that it does so outside *their* system of approval and control. The complaint is not that the license makes them unfree. The complaint is that the license is *free of them*. + +.. _brandolinis-distribution-argument: + +The Distribution Argument +^^^^^^^^^^^^^^^^^^^^^^^^^ + +A recurring companion claim is that RNS is not properly "distributed", usually deployed as "it's not packaged as a .deb" or "it's not on package manager X", with the implication that it is somehow unavailable or inaccessible, or hard to install on a given system. + +This is simply false, and it has been false for years. The reference implementation is available on practically every platform and architecture with a single command (\ ``pip install rns``\ ). It is packaged in the Arch User Repository, in NixOS, and in a range of other distribution channels, community-maintained and official. It can be installed, updated, and kept current *over Reticulum itself* - the network transports its own software updates. It is used on more than a hundred thousand devices worldwide, is embedded in over a hundred other packages and applications, and carries terabytes of traffic every day. + +The claim that Reticulum needs a ``.deb`` to be "really distributed" mistakes the mechanism for the goal. The goal is that people can obtain and update the software easily, everywhere, **on their own terms**, and distribute it themselves, both offline, online and over Reticulum with full cryptographic verification of the install packages, without any central infrastructure. + +That goal is met to an excellence that few software packages can speak of, and met in a way that does not pin the project's release cadence to the review cycles of distribution maintainers, which is an achievement, not a bug. + +A project like RNS that updates continuously, sometimes daily, and has a track-record of shipping security updates mere hours after issues are discovered, would be crippled by packaging that makes every change wait months for approval. The distribution complaint is a strawman generated for the occasion. It has been answered, in public, many times; it is repeated anyway, because the people repeating it are not counting on facts - they are counting on the reader never having heard the answer. + +.. _brandolinis-on-institutions: + +On The Institutions, In Fairness +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +None of the above is hostility toward the Open Source Initiative or the Free Software Foundation as institutions, nor toward the individuals who have dedicated decades of work to them. Their contribution to the world of software is **enormous**\ , and this document does not dispute it. What is disputed is a specific claim of authority: That "open source" is a term whose meaning is reserved to a committee's approval, and that a license which does not submit itself to that approval is therefore not open. + +That claim of authority is not in Reticulum's interest, and it is not in the interest of the people the movement claims to serve. The current legal and technological landscape - the machine-appropriation of the commons, the weaponisation of "prior work" generation, the erosion of human agency by synthetic systems - was not anticipated by the DFSG of 1997, and the institutions have not, as of this writing, produced *any* meaningful answer to it. The choice, as it was put at the time of the license change, is whether developers should sit back and wait for a solution from a committee that "may or may not ever materialize, before the entire foundation we stand on has been eaten away". + +**Reticulum's answer was to act**. If we had waited, it would have been too late. + +If an OSI-approved license existed that expressed the same constraints - and did not impose the far more severe restrictions of copyleft - the project would have used it. None such exists. That is not Reticulum's failure. It is the measure of what the definition is missing. + +.. _brandolinis-what-open-means: + +What "Open" Means Positively +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For anyone who wants the positive statement rather than the rebuttal, Open Source, in this project's understanding, means: + +* The source code is available, to everyone, without charge +* Everyone may use, copy, modify, merge, publish, distribute, sublicense, and sell the + software +* No one is discriminated against as a person - developer, user, community, or project +* The protocol itself is dedicated to the public domain, where no one can own it +* And the single, plainly stated condition of the license is that the work shall not be + consumed to harm human beings, or ingested to replace the humans who made it + +If that is not "open" by a definition written in the 1990s, then the definition is the thing +that has failed - not the software, and not the people who use it. + +**Open source means open source**. It was true before the committees existed to certify it, and it will remain true after they are gone. + +.. _brandolinis-assistance-versus-substitution: + +Assistance Versus Machine-Substitution +-------------------------------------- + +.. _brandolinis-false-dichotomy: + +False Dichotomy +^^^^^^^^^^^^^^^ + +The public discussion around machine learning and software development has been derailed, by the loudest voices on both sides, into a farcical fight between "AI enthusiasts" and "AI haters". + +.. + + **Both positions are absolute caricatures.** + + **The fight is beside the point in the ways that matters most.** + +It is not an accident, but a very conscious choice that the initial analysis of the Prns case examined herein, and this very chapter, were themself produced with the assistance of a machine-learning based generative system. + +Specifically, it was generated using ``lc`` managing a ``Q8_K_XL`` quant of ``DeepSeek v4 Flash`` running in the ``llama.cpp`` inference engine. The main context base used to stabilize, ground and inform the generative environment consisted of approximately 100,000 tokens of text material that I personally thought out and wrote (by hand), then archived and organized, over the last eight years. + +If you know my writing, and have a hard time discerning where this chapter is me directly, typing manually, and where it is the machine output, it is because of two things: Almost every line in this chapter was either directly edited by my hands on the keyboard or typed by me, and the text corpus that informed the process *is* genuinely me - my thoughts, written by me, over a period of years. + +The chapter was produced this way *deliberately and openly*, under a software framework I designed and wrote, with the human directing the inquiry points, flow of investigation, structure of the outputs, contents of every section, making the editorial decisions, reviewing the conclusions, painstakingly adjusting every line, and taking responsibility for the final claims presented, with the goal of reaching a higher level of synthesis and symbolic density than I could have achieved without that assistance. + +The tool was *used as tool*, both to structure and produce a complex chapter, and to inspect a repository so preposterous in size, commit velocity and nonsensical wording that it barred any purely human inquiry. + +As such, the position is hereby, by personal example and demonstration, stated clearly: + +* **Technological assistance is not the problem** +* **It was never the problem** +* **It is the opposite of the problem** + +The problems are *substitution* and *usurpation*\ : The perverse process in which the machine becomes the author of choices, and the human becomes the facade of software, while expecting "reciprocity" or recognition for deeds they never performed. + +.. _brandolinis-the-line: + +The Line +^^^^^^^^ + +The exact distinction can be reduced neither to how many lines of code a machine produced, nor who pressed the keys. The final distinction has to rest on **who, or what, the real agent of the work is**. + + +* **Assistance** is when the human retains the full seat of agency: The human decides what to build, judges + what is correct, rejects what is wrong, understands what is shipped, and can answer for every single line of it. + The machine writes, suggests, drafts, accelerates *meaningfully* and within reason - but every choice that survives into the + final work is a choice the human made *consciously*\ , and understood - or grew to understand - the consequences of. +* **Substitution** is when the machine *becomes* the agency: the machine decides what to build, + decides what is correct, iterates on its own errors, generates at a scale and speed no single + human can follow - and the human's role is reduced to providing the name, the account, the + signature, and the marketing launch. + +.. + + The Line can be stated as a single test, and this is the same test that has always separated authorship from couriership: **Can the person whose name is on the work answer for it fully?** Not "can they describe what it does" - can they account for why it is the way it is, line by line and decision by decision, and the history of how it came to be that way, under questioning, without machine assistance, including by people who know more than they do? + +If they cannot, they did not author the work. They wore it, or in more severe cases, they stole it. And a courier who claims authorship is not a writer; they are a fraud. + +.. _brandolinis-what-assistance-looks-like: + +What assistance looks like +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Assisted work is recognisable, and recognisability is itself part of its value. It has the following observable properties: + +#. **The human can explain it.** Under examination, the author can say why this choice was + made, what was rejected, and what they verified. The ability to explain is not a luxury; + it is the very demonstration of authorship. On a large project with many contributors this is partial in + practice - no one can explain every line of a large codebase - but the *full capacity* must + exist between the authors and the *habit* must be visible. +#. **The human can, and does, reject machine output.** An author who has never rejected the machine's output is not + an author, but an open drain. Rejection is not a stylistic flourish; it is the + mechanism by which any work attains Quality. A record of decisions, including reversals and rejections, + is a sign of agency. A record without rejection is a record of assent-by-default. +#. **The human's judgment is directional.** The work contains the human's actual choices; + things the machine would not have decided on its own, which the human can defend on their + merits. This directionality has many names in engineering: Design, architecture, taste, + judgment. Where it is absent, the work has the uniform, self-consistent texture of + something that was never doubted, and doubt is exactly what anything important requires. +#. **Provenance is not concealed.** Disclosure of how the work was made is not a legal + requirement in every jurisdiction; it is not even always a practical requirement. But it + is a *statement* that matters. A project that discloses its process - + including its use of machines - is telling the truth about the relationship between the + human and the work, and that is a property users *are* entitled to know. Concealment of + provenance is not a stylistic choice; it is deception, made by someone who knows what the + record would otherwise show. +#. **The human stands behind the failures.** When assisted work fails, the human can say: Yes, I + chose this, under these assumptions, here is why, here is what I got wrong, here is the fix. + That sentence is the entire contract between an author and the people who depend on their work. + A human who cannot say it - because the choices were never theirs - *has nothing to offer anyone*\ , and + is by definition entirely replaceable; anyone else could have pressed the same button. + +.. _brandolinis-what-substitution-looks-like: + +What substitution looks like +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Substitution is equally recognisable, once the pattern is known: + +#. **Scope that no human could have authored.** Output that + structurally cannot have been the product of human authorship, review, and judgment, for + example when the volume exceeds any reasonable human capacity within the span of the project's life. + When the review capacity and the output volume are incommensurable, the output was not + reviewed. It was generated, then forgotten, and the record was signed blindly. +#. **Uniform generation.** The work carries no trace of a human's changing mind. No style + drift, no contested decisions, no "we tried X and it was wrong, so we did Y". That is, *no + signs of actual development, growth and learning*. Instead, endless, self-referential + refactoring, renamed abstractions, and the same fluent register in every commit, + every document, every reply. A human's history shows the wear of judgment. + Pure generation shows the superficial polish of its absence. +#. **Discovery by recursive regeneration.** When errors are found, they are found by the machine's own + subsequent runs, not by human scrutiny - and the findings are recorded as planned + "reviews" and "alignments" rather than as the corrections they are. This is the tell: A + machine editing its own previous output, while the edit is recorded as if it were a + scheduled milestone. That's not review. That's a continuous generation loop revising itself, + with the attempt of an illusion-preserving voice-over. +#. **Laundered provenance.** Theatrical concealment machinery: Commit hooks that refuse + attribution of machine generation, contribution policies that declare machine output + "yours", processes that scrub personal traces from the history, fake identities in the + contributor list. All of these have one function: To make the record say what the "author" + *wished* had happened, rather than what happened. A project that builds such machinery is + not making a record of its work; it is using automated software to manufacture one. +#. **Authorship by assignment.** The human's name is on the work, but the human cannot + answer for it - because the human did not choose any of it, and knows it. The name is not a + signature of authorship; it is a *fraudulent claim of ownership* over something the claimant did not + make and cannot explain. In every field that has ever dealt with such claims - art, + literature, invention, journalism - *this has a name*. That **forgery** is now cheap in software + makes it no more forgivable. + +.. _brandolinis-infrastructure-matters: + +Infrastructure Matters +^^^^^^^^^^^^^^^^^^^^^^ + +For a hobby project, the distinction between assistance and substitution is a personal matter. For infrastructure - code that other people's communications, safety, and freedom run on - it is a matter of life and safety, and any statement about this must be entirely unapologetic. + +Infrastructure has one property that distinguishes it from almost all other software: While most of the people who depend on it cannot verify it themselves, **it must be verifiable, auditable and open to human inspection**\ , and be engineered in such a way that this is as frictionless and straight-forward as possible. + +The reference implementation of Reticulum was designed this way, and continues to make that goal a primary one. While it *is* a complex piece of software, with an intricate array of interlocking and moving parts, the core parts of RNS, the entire Reticulum protocol implementation, the transport logic, the cryptographic primitive interfaces, **is less than 15,000 lines of code**. That line count even includes the rather extensive comments, incredibly detailed logging facilities and other choices that makes the code easy to read and understand for humans, and easy to operate, verify and debug. It took real dedication, and *a lot* of hard work to achieve that. + +Exactly because not *everyone* can do this, it is a fundamental necessity for infrastructure software that it is designed and authored so that *as many as possible can*\ , and that the *chain of accountability* - who made it, who reviewed it, who answers for it - is held intact at every link. That chain is not decoration. It is the entire mechanism by which normal users decide to trust a system they cannot fully verify. The transparent foundations and the chain combined *is* the verification for most users. + +Substitution breaks the chain both at the foundations, and at its load-bearing link: The human at the top can no longer answer, because they were never the maker. Unfortunately, the chain does not always fail visibly; often it fails silently, at the exact moment a question goes deep, or when routing fails subtly at a critical moment. + +For the user, the result is not a project with a normal and humanly flawed author - it is a project *with no author at all*\ ; a signature with no substance behind it, a name that cannot be held to account, and a body of work that nobody on earth can (or wants to) explain, defend, or fix in a crisis. + +.. _brandolinis-the-fluency-trap: + +The Fluency Trap +^^^^^^^^^^^^^^^^ + +It is worth understanding, briefly, why substitution is so attractive and so dangerous at once. Machine-generated output is fluent. It is confident, well-structured, and terminologically *self-consistent*. At the surface, and from the perspective of someone outside a given craft, it is indistinguishable from the output of a knowledgeable human. Fluency of this kind can be a useful property: It makes assisted work fast. But fluency is *not* understanding. It is the *minimal conformal surface* of understanding. + +The danger is that the surface is exclusively where the substituter invests; for the simple reason that the surface is where most of the desired audience looks, and what yields attention to the project. + +A human who can tell the difference uses the tool well. A human who cannot is being deceived through means they cannot detect from inside, namely through their own inability to account for the limits imposed by what they do not know. + +This is why the most important quality for anyone working with systems like Reticulum is not speed, and not vocabulary, but the oldest engineering virtue there is: The honest, uncomfortable, terrorizing knowledge of **what you do not know**. The substitute *never* has it. The substitute's operator, *if* they ever had it, loses it precisely the moment they accept the fantasy of the substitution process. + +The tool is not the hazard, plain old human nature is. The tool is a mirror, and mirrors - as has been observed for rather longer than software has existed - show the truth only to those willing and yearning to see their own shortcomings. + +.. _brandolinis-disclosed-assistance: + +Disclosed Assistance Or Laundered Generation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The contrast at the centre of this entire discussion can be made clearer with two examples, both of which are publicly accessible, both produced in the same year, by people using the same class of tools. + +The first is this chapter. It was produced with machine assistance, openly: the structure was directed by the human, the material was assembled with the tool's help, every conclusion, every line, every slight nuance of meaning and semantics was examined, edited, and accepted or rejected by the human, and the process described publicly - including the precise characteristics of the technological assistance framework used. The human can answer for every claim in these documents, because the human made the decisions the claims rest on. + +The second is the project examined in :ref:`the Prns case`. It was produced by a machine, at a volume no human could review, and the authorship record was engineered to erase the machine's role: A commit hook that refuses attribution of machine generation, a contribution policy declaring machine output the human's own, a fictitious contributor identity, 637,000 lines of unreviewed code. The human cannot answer for the code, because the choices were never made by a human - only the conformal surface of the presentation was. + +The same tool class. The same technology. Two diametrically opposed relationships to truth and responsibility. **The difference is not the tool**. The difference is the presence or absence of the human as the agent of the work - and the honesty or concealment with which that relationship is recorded. + +Assistance leaves the human as the agent and the commons as the source from which the human works and can grow. Substitution removes the human from the loop and converts the commons into fuel for the thing that seeks to replace them, or usurp their work for the profit of the few, human atrophying in the process. + +.. _brandolinis-license-in-context: + +The License In This Context +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Reticulum License, examined in :ref:`What The Reticulum License Is`, draws the same line, at the level of the law. Its AI condition does not forbid the use of machine-learning technology to *assist* development - no reading of the license could support that, and no one associated with this project has ever claimed so. What the condition forbids is the *appropriation of the work into the machine itself*\ : The ingestion of the commons as raw material for synthetic replacement, and the concealed fabrication of "prior work" that would bury the real thing. + +As also noted in :ref:`Copyright & The Two Legal Layers`, plain old copyright law already protects against the case where a process copies the reference implementation into a machine, produces a transformed derivative, and then claims "Copyright, [name of the process operator]", with no human able to account for the creative decisions in the result. That is simple, petty theft, as it always has been. + +.. _brandolinis-general-principle: + +The General Principle +^^^^^^^^^^^^^^^^^^^^^ + +In these regards, the position of this project can be codensed to something relatively concise: + +* Machine assistance in human learning, development, and creation is accepted and useful. + It is not a shameful secret; but it *is* a tool that needs knowledge, training, understanding, + and great care to use. It should not make anything easier or more fun, it should make the + results better, more carefully considered, and arrive at *higher levels of synthesis*\ , not + produce endless streams of code churn. +* The line is crossed when the human stops being the agent of the work. When *any* output is + accepted that the human cannot explain, produced at a scale the human cannot review, or filed under a record + where the human has arranged to conceal the fact. +* The line is crossed, when a human claims authorship of work they cannot + answer for or has usurped. Credit follows the ability to answer. It has always worked that way, and + machines do not change the rule - they only make it cheaper and more tempting to break. +* The people who depend on infrastructure have the right to know which side of the line + the code they run was made on. That knowledge is the only verification most of + them will ever be able to perform. + +Use assistance, by all means, *and learn*\ , but don't substitute. And never sign what you cannot answer for. + +Somewhere, within the general shape of the conceptual framework outlined in this section, or realistically, a more refined variant of it, I do believe there is the *potential* of the *beginning* of a constructive outcome to the immense challenge we are faced with as a species in regards to these problems. + +At the same time, I reserve my right to revert that position to Butlerian Jihad without prior notice. We are on a knife's edge, and you know it just as well as I do. + +.. _brandolinis-void-grants: + +Void Grants: Legal Foundations of Machine-Generated Code +-------------------------------------------------------- + +A grant of rights is only as real as the rights behind it. A license conveys what its issuer holds, and nothing more. A derivative may be distributed only under whatever license covers what it took. And over a work that a machine originated, no human holds anything at all. + +Each of these statements is a matter of settled statute and case law, and this section sets out the authorities. The conclusions they support are: + +#. A software implementation generated from a licensed work by a machine, published under its operator's claimed copyright and license, **conveys rights the operator never possessed**. +#. **Its grant is void**. The projects, products, and promises built upon such grants stand on nothing. A field of void grants is a minefield for everyone who crosses it. + +This section is a general examination of copyright law as it applies to machine-generated code. It is not legal advice. + +I. The Foundational Statute: Translation Is Copying +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The starting point is the statutory definition of the class of works at issue. Title 17, United States Code, section 101 provides the definition of a derivative work: + +.. + + A "derivative work" is a work based upon one or more preexisting works, such as a *translation*\ , musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or *any other form in which a work may be recast, transformed, or adapted*. + + +Section 101 further provides that *"the terms 'including' and 'such as' are illustrative and not limitative"*. As such, the list is a list of *examples*\ , and the very first example is translation. The definition also reaches, in its own words, *"any other form in which a work may be recast, transformed, or adapted"*. + +The exclusive right at issue is defined in section 106: + +.. + + Subject to sections 107 through 122, the owner of copyright under this title has the exclusive rights to do and to authorize any of the following: + (1) to reproduce the copyrighted work in copies or phonorecords; + (2) to prepare derivative works based upon the copyrighted work; + (3) to distribute copies or phonorecords of the copyrighted work to the public by sale or other transfer of ownership, or by rental, lease, or lending; + + +Violation of any of these rights is infringement. 17 U.S.C. § 501(a). + +Taken together, the provisions yield a construction that is difficult to improve upon and impossible to escape: + +#. **A port is a translation.** A work that takes a program written in one language and from it produces a program written in another language, implementing the same behavior, is a translation of the original - whatever mechanism performed it, and however the surface presentation differs. +#. **A translation is a derivative work.** Section 101 says so, explicitly. +#. **Preparing a derivative work is the copyright owner's exclusive right.** Section 106(2) says so explicitly. A derivative work prepared without authorization, or outside the scope of any authorization, infringes that right. + +The common objection - "the code is in a different language, so it is completely different" - is not a legal argument; it is the definition of what the statute already classifies. + +Translation *is the paradigm* of derivative authorship, not an exception to it. If translating a work without permission was a defense, the derivative-work right would be meaningless; every infringing adaptation would simply need to be "different enough" to count as a translation of its source. + +Nor does the identity of the translator change the analysis. The statute asks whether the work is "based upon" a preexisting work. It does not ask who or what performed the translation. A machine that ingests a licensed work and reproduces a translated transformation of it has performed mechanical translation; the output is a derivative of the ingested work, and the law governing derivative works applies to it exactly as it applies to a translation made by hand. + +II. Ideas Are Free, Expressions Protected +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The second foundation is the distinction between what a work *is* - its ideas, its processes, its systems - and the *expression* in which those ideas are embodied. The distinction is codified in section 102(b): + +.. + + In no case does copyright protection for an original work of authorship extend to any idea, procedure, process, system, method of operation, concept, principle, or discovery, regardless of the form in which it is described, explained, illustrated, or embodied in such work. + + +The principle is older than the statute, and its application to software is settled. An author may own the particular code in which a method is expressed; the method itself, the process, the algorithm, belongs to no one - because *"the sine qua non of copyright is originality"* (\ *Feist Publications, Inc. v. Rural Telephone Service Co.*\ , 499 U.S. 340, 345. 1991). And ideas are not original to anyone in particular, *Baker v. Selden*\ , 101 U.S. 99 (1879), established the line: Copyright in a book describing a system does not prevent others from practicing the system. + +Applied to a communications protocol, the structure is clean: + +---- + +**An implementation of a public-domain protocol, honestly reasoned and written by humans, is welcome and unencumbered, and owes nothing to any license. An implementation generated from a licensed implementation is a derivative of licensed work, subject to its conditions and to the ordinary copyright of its source.** + +---- + +The public-domain status of the protocol's ideas changes nothing about the copyright in an implementation's expression. A person who copies an implementation - by machine or by hand - cannot defend the copying by pointing to the protocol, because the protocol covers the ideas, not the symbols in which someone expressed them. + +A further misconception can be dismissed here; the recently popularized "clean-room" claim about the absence of copying. A :ref:`clean-room` is a not a magic label achievable by LLM, but a specific, institutionalized procedure for proving to a court that copying did not occur: Physically separated teams, written functional specifications, attestable non-exposure, and no access to the original by the implementers (\ *Altai*\ , 982 F.2d at 709–11). + +*"I created a clean-room implementation by feeding the original source code into a machine"* attempts to *claim* the certified, legally established procedure for proving the absence of copying by describing, in the same breath, a process **composed entirely of copying**. The word is deployed because the procedure it names is what the claimant would *need to have happened*. + +III. Machine Output Has No Author +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The third foundation is the human authorship requirement. It is settled at both levels of the federal courts and in the Copyright Office's administering practice. + +In *Thaler v. Perlmutter*\ , the district court held that *"copyright law protects only works of human creation,"* and that *"human authorship is a bedrock requirement of copyright"* (687 F. Supp. 3d 140, 146, D.D.C. 2023). On appeal, the United States Court of Appeals for the District of Columbia Circuit affirmed, holding that the Copyright Act *"requires all eligible works to be authored in the first instance by a human being"* (No. 23-5233, D.C. Cir. Mar. 18, 2025). + +The requirement traces to the ordinary meaning of the statutory term. In *Burrow-Giles Lithographic Co. v. Sarony*\ , the Supreme Court defined an "author" as *"he to whom anything owes its origin; originator; maker; one who completes a work of science or literature"* (111 U.S. 53, 57–58, 1884), and more recently described the author as *"the person who translates an idea into a fixed, tangible expression entitled to copyright protection"* (\ *Community for Creative Non-Violence v. Reid*\ , 490 U.S. 730, 737, 1989). + +---- + +**A machine does not owe expression its origin; it reproduces it. No court has recognized copyright in material created by non-humans, and the courts that have addressed the question have rejected it. If you create by machine generation, you do not own the output.** + +---- + +The Copyright Office's registration guidance applies the requirement to generative systems in terms that are directly on point. The Office asks: + +.. + + whether the "work" is basically one of human authorship, with the computer [or other device] merely being an assisting instrument, or whether the traditional elements of authorship in the work (literary, artistic, or musical expression or elements of selection, arrangement, etc.) were actually conceived and executed not by man but by a machine. + + + +* *Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence*\ , 88 Fed. Reg. 16190, 16192 (Mar. 16, 2023) + +And it states the consequence: *"If a work's traditional elements of authorship were produced by a machine, the work lacks human authorship and the Office will not register it"* (\ *Id.*\ ). + +On the role of prompts, the Office is equally explicit: when a system receives a prompt and produces a work in response, *"these prompts function more like instructions to a commissioned artist - they identify what the prompter wishes to have depicted, but the machine determines how those instructions are implemented in its output"* (\ *Id.*\ ). + +The agency applied this standard and excluded machine-originated material from registration in the leading administrative case. In *Zarya of the Dawn* (Cancellation Decision, Feb. 21, 2023, Registration No. VAu001480196), the Office cancelled registration of images generated by the Midjourney service, holding that *"it was Midjourney-not [the author]-that originated the 'traditional elements of authorship' in the images"*\ , while preserving protection for the human-authored text and the human selection and arrangement of the work. + +The Copyright Office's 2025 report on AI copyrightability reaches the same conclusion: + +.. + + Based on the functioning of current generally available technology, prompts do not alone provide sufficient control. + + + +* U.S. Copyright Office, *Copyright and Artificial Intelligence, Part 2: Copyrightability*\ , at iii (Jan. 29, 2025) + +The report's analysis is explicit: *"The Office concludes that, given current generally available technology, prompts alone do not provide sufficient human control to make users of an AI system the authors of the output. Prompts essentially function as instructions that convey unprotectible ideas"* (\ *Id.* at 18). + +Its guiding distinction is stated plainly: *"The use of AI tools to assist rather than stand in for human creativity does not affect the availability of copyright protection for the output"* while *"Copyright does not extend to purely AI-generated material, or material where there is insufficient human control over the expressive elements"* (\ *Id.* at iii). + +The boundary is therefore not "AI or no AI". It is *assistance or substitution*\ : Whether a human exercised sufficient creative control over the expressive elements and can answer for them, or whether the machine originated them and the human merely supplied instructions and a signature. That is a question of fact in each case, determined from the record of how the work was made. + +Two facts follow, and stated together, they form the base legal reality: + + +#. **A work whose expressive elements were originated by a machine contains no valid new copyright: It has no human author. To the extent that the same work reproduces a preexisting copyrighted work without explicit license, it is at the same time an unauthorized derivative. It is unowned for anything new it contains, and unlicensed for everything taken.** +#. **Its operator therefore holds no copyright in it and no grant over it - and a person who holds neither copyright nor grant can convey neither.** + +The first fact makes the work **unownable** by its operator. The second makes it infringing against its source. Neither replaces the other: + + +* The absence of copyright in machine output does not make the output free for anyone to take; it makes it unowned. +* This is a different thing entirely, especially when what it contains is someone else's expression. + +IV. License Conditions Bound the Grant +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The fourth foundation governs what a license *is*. A copyright owner may grant permission to use the work on conditions. The conditions define the scope of the permission. Use outside the scope is use that was never authorized. + +In *Jacobsen v. Katzer*\ , 535 F.3d 1373 (Fed. Cir. 2008), the Federal Circuit held that the conditions of an open-source license are *conditions of the copyright license itself*\ , not mere contractual promises, and that a licensee operating outside them is an infringer: + +.. + + Copyright holders who engage in open source licensing have the right to control the modification and distribution of copyrighted material. + + The choice to exact consideration in the form of compliance with the open source requirements of disclosure and explanation of changes, rather than as a dollar-denominated fee, is entitled to no less legal recognition. + + It is outside the scope of the [license] to modify and distribute the copyrighted materials without copyright notices and a tracking of modifications from the original computer files. + + + +* *Id.* at 1381–82 + +The doctrinal mechanism is settled: *"A copyright owner who grants a nonexclusive license to use his copyrighted material waives his right to sue the licensee for copyright infringement"* within the scope of the license. If, however *"the licensee acts outside the scope, the licensor can bring an action for copyright infringement"*\ : An act outside the granted scope **is infringement** (\ *Sun Microsystems, Inc. v. Microsoft Corp.*\ , 188 F.3d 1115, 1121, 9th Cir. 1999; *Graham v. James*\ , 144 F.3d 229, 236, 2d Cir. 1998; *S.O.S., Inc. v. Payday, Inc.*\ , 886 F.2d 1081, 1087, 9th Cir. 1989). + +Whether a given license term is a condition of the grant or a mere covenant is determined from the license's own language; conditions that limit what may be copied, modified, and distributed - the attribution terms, the notice terms, the modification-tracking terms, the field-of-use terms - are the boundaries of the copyright grant (\ *MDY Industries, LLC v. Blizzard Entertainment, Inc.*\ , 629 F.3d 928, 940, 9th Cir. 2010). + +Three consequences follow for the analysis at hand. They are not hypothetical. + +**First, the conditions are measured at the moment of copying** + +A work is licensed under whatever conditions applied when the reproduction, adaptation, and distribution occurred. There is **no** period in which copying a licensed work is "free" because the copy was made by a machine; the machine is the *licensee's tool*\ , and the licensee is bound by the conditions regardless. A derivative generated without satisfying the conditions - without the attribution, without authorization for the manner of use - was never within the scope of the license, from the first instant of its existence. + +**Second, breach does not restore rights that never attached** + +The district court in *Artifex Software, Inc. v. Hancom, Inc.*\ , No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017), analyzing the GPL's termination provisions, observed that *"the language of the GPL suggests that [the licensee's] obligations persisted beyond termination of its rights to propagate software using Ghostscript,"* because the source-code obligation recurs each time a covered work is conveyed. The same structure operates a fortiori where a derivative was produced *outside* the license entirely: No grant ever attached, and no subsequent event creates one. + +**Third, the settled conditions are the enforceable core** + +The attribution and notice conditions rest on the settled doctrine above. Novel conditions (restrictions on field of use, restrictions on how the work may be consumed) are enforceable as conditions of the grant when clearly drafted, but their enforcement history is thinner. The argument that a derivative is unlicensed does *not* depend on the novel conditions being vindicated; it needs **only** the settled ones, and the ordinary law of derivative works, to stand. + +V. The Void Grant +^^^^^^^^^^^^^^^^^ + +The preceding sections assemble into a single structure. Let us apply it to an example situation: + + +* A project presented as an independent implementation of a protocol; "ground-up", "from scratch" or "clean-room" work. +* The actual history shows continuous, machine-mediated ingestion of a licensed reference implementation. +* The output is generated at a scale no human could produce or review, with the provenance of the process obscured. + +**Step One: The derivative** + +The project's output is a translation of the licensed implementation: A derivative work, produced by a copy process. 17 U.S.C. §§ 101, 106(2). Preparing it without authorization infringed from the first moment of its existence. *Id.* § 501(a). + +**Step Two: The license** + +The derivative was produced outside the conditions of the license; without the notices, without the attribution. The license never attached (\ *Jacobsen*\ , 535 F.3d at 1381–82). + +**Step Three: Authorship** + +The expression was originated by a machine. No human can account for its creative decisions, and no human authored it. It contains no valid new copyright (\ *Thaler*\ , 687 F. Supp. 3d at 146; No. 23-5233, D.C. Cir. 2025; 88 Fed. Reg. at 16192). + +**Consequence: Void Grant** + +The statute supplies the consequence. Section 103(a) provides: + +.. + + The subject matter of copyright as specified by section 102 includes compilations and derivative works, but protection for a work employing preexisting material in which copyright subsists does not extend to any part of the work in which such material has been used unlawfully. + + +And section 103(b) provides that copyright in a derivative work *"extends only to the material contributed by the author of such work."* The legislative history states the point without ambiguity: *"An unauthorized translation of a novel could not be copyrighted at all"* (H.R. Rep. No. 94-1476, at 57, 1976). + +In our example, the operator of the derivative's copy process decides to assert copyright over the output, and licenses it to the world under terms of the operator's choosing, for example the Apache License. + +But the operator holds no copyright in machine-originated content (section III) and no license over the source from which it was derived (sections I and IV). + +For the derived material, the operator's copyright claim **is an assertion of a right that never existed**. The material was used unlawfully, and section 103(a) withholds protection from *every* part of the work in which it appears. For the machine-originated remainder, the operator holds no copyright either, for lack of any human author. + +The operator's license to the world is a promise the operator had no power to make. Every person who receives the work believing they received a valid grant has received **a void grant**\ , and stands, as a matter of settled law, in the position of a downstream user of an unauthorized derivative, whatever they were told at the time. + +This is a cascading consequence, and it is why the pattern is a hazard. No combination of self-granted licenses - "MIT," "Apache," "public domain," anything at all - can transfer rights the operator never held. Every downstream project, product, or deployment built on the derivative is built on unlicensed reproduction of a third party's work, whether or not it knew, whether or not it was told, and whether or not the marketing was plausible. + +The longer the derivative circulates unexamined, the more it becomes embedded, forked, vendored, depended upon, and the more expensive its correction becomes for everyone who trusted it. A field of superficially real projects, repositories, and licenses that **in reality confer nothing on anyone who relies on them is a minefield**\ , in the most precise sense the law allows: The rights they purport to grant *were never possessed*. + +The law defines what may be asserted, not what will be. The copyright owner may choose whether and how to assert these rights, and at what point in time. The exposure exists regardless, and for *every* downstream that trusted the void grant. This is the scope of the hazard that the conduct exemplified here produces. + +VI. Fair Use Does Not Rescue This Pattern +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Every defendant raises fair use. It is an essential and important limitation in the service of free speech, accountability, criticism, education and other important domains. Therefore, it must be considered, and in the case exemplified here, it fails. + +Fair use is a limitation on the exclusive rights, evaluated case by case under four factors: The purpose and character of the use; the nature of the copyrighted work; the amount and substantiality of the portion used; and the effect of the use on the potential market for or value of the work (17 U.S.C. § 107). + +On the first factor, the governing standard is *Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith*\ , 598 U.S. 508 (2023), in which the Supreme Court held that: + +.. + + In sum, the first fair use factor considers whether the use of a copyrighted work has a further purpose or different character, which is a matter of degree, and the degree of difference must be balanced against the commercial nature of the use + + +The question is whether the use serves a further purpose, not whether the surface changed. A derivative that exists to serve as the same thing as the original, marketed to the people who would otherwise use the original, has not acquired a further purpose by being translated; the surface changed, the function did not, and the use is commercial. + +The remaining factors resolve the same way. Source code is expressive creative work, not bare fact. The pattern under examination copies the whole; a complete implementation, ingested and translated in its entirety. And the market effect is the decisive factor, because it is engineered: A derivative marketed as a drop-in replacement for the work it was copied from is not a complement to the original's market, it is a substitute for it. The Supreme Court has long held that use of a work to satisfy the market demand for the original is the paradigm of an *unfair* use (\ *Harper & Row, Publishers, Inc. v. Nation Enterprises*\ , 471 U.S. 539, 566–67, 1985). + +The one case that is always raised in response, *Google LLC v. Oracle America, Inc.*\ , 593 U.S. 1 (2021), holds less than it is believed to. The Court there assumed *"for argument's sake, that the material was copyrightable"* and held *"that the copying here at issue nonetheless constituted a fair use"* (\ *Id.* at 11). + +The material in question was a thin slice of *declaring code*\ , which the Court found sits, *"if copyrightable at all, further than are most computer programs (such as the implementing code) from the core of copyright"* (\ *id.*\ ), in a use that built a new platform for a new environment, with the copier **having written the vast majority of its own code**. By comparison: A wholesale translation of an entire implementation, marketed as a substitute for it, is **not** that case; it is the other end of every factor. + +The valuable zones of fair use remain, and they are important. **Commentary and criticism**\ , quoting from a work to review, discuss or criticize it. **Teaching and scholarship**\ , explaining concepts and quoting excerpts, is its traditional beneficiary. + +Conclusion +^^^^^^^^^^ + +The law is neither obscure nor new. The conclusion it yields can now be stated: + + +* A machine translation of a protected implementation **is a derivative work**, and an unauthorized derivative **is an infringement**, whatever language it speaks and whatever machinery produced it. +* A work whose expression a machine originated has no human author, no valid new copyright, and without valid copyright **no license can be granted on it**. +* § 103 withholds protection from every part of a derivative in which protected material was used unlawfully. A license is a grant with conditions, and a derivative made outside the conditions **never received a grant**. +* A person who holds no copyright and no grant **can convey neither**, and *every* downstream consumer who received from them received a **void grant**. + +This is a *catastrophic* failure state for all who want to create things good and useful: The projects that inherit only void grants and liability believing they have inherited foundations, the users who depend on code that no one on earth can answer for, the honest builders whose work is buried under a field of plausible-looking impostors. + +Sources and Authorities +^^^^^^^^^^^^^^^^^^^^^^^ + +Statutory references are to Title 17, United States Code. Case citations are to the official or generally cited reporters. Online links are for reference only. Section numbers refer to the sections in which each authority is principally relied upon. + +**Statutes** + + +* `17 U.S.C. § 101 (definitions: "derivative work," "including," "publication") - I, II `_ +* `17 U.S.C. § 102(b) (idea/expression) - II `_ +* `17 U.S.C. § 103(a)–(b) (derivative works employing unlawfully used preexisting material) - V `_ +* `17 U.S.C. § 106(1)–(3) (exclusive rights: reproduction, derivative works, distribution) - I `_ +* `17 U.S.C. § 107 (fair use) - VI `_ +* `17 U.S.C. § 501(a) (infringement) - I, V `_ + +**Judicial decisions** + + +* `\ *Jacobsen v. Katzer*\ , 535 F.3d 1373 (Fed. Cir. 2008) - IV, V `_ +* `\ *Sun Microsystems, Inc. v. Microsoft Corp.*\ , 188 F.3d 1115 (9th Cir. 1999) - IV `_ +* `\ *Graham v. James*\ , 144 F.3d 229 (2d Cir. 1998) - IV `_ +* `\ *S.O.S., Inc. v. Payday, Inc.*\ , 886 F.2d 1081 (9th Cir. 1989) - IV `_ +* `\ *MDY Industries, LLC v. Blizzard Entertainment, Inc.*\ , 629 F.3d 928 (9th Cir. 2010) - IV `_ +* `\ *Artifex Software, Inc. v. Hancom, Inc.*\ , No. 16-cv-06982-JSC (N.D. Cal. Sept. 12, 2017) (settled; dismissed with prejudice Jan. 2018) - IV `_ +* `\ *Thaler v. Perlmutter*\ , 687 F. Supp. 3d 140 (D.D.C. 2023), aff'd, No. 23-5233 (D.C. Cir. Mar. 18, 2025) - III, V `_ +* `\ *Burrow-Giles Lithographic Co. v. Sarony*\ , 111 U.S. 53 (1884) - III `_ +* `\ *Community for Creative Non-Violence v. Reid*\ , 490 U.S. 730 (1989) - III `_ +* `\ *Feist Publications, Inc. v. Rural Telephone Service Co.*\ , 499 U.S. 340 (1991) - II `_ +* `\ *Baker v. Selden*\ , 101 U.S. 99 (1879) - II `_ +* `\ *Computer Associates International, Inc. v. Altai, Inc.*\ , 982 F.2d 693 (2d Cir. 1992) - II `_ +* `\ *Andy Warhol Foundation for the Visual Arts, Inc. v. Goldsmith*\ , 598 U.S. 508 (2023) - VI `_ +* `\ *Google LLC v. Oracle America, Inc.*\ , 593 U.S. 1 (2021) - VI `_ +* `\ *Harper & Row, Publishers, Inc. v. Nation Enterprises*\ , 471 U.S. 539 (1985) - VI `_ + +**Administrative and policy authorities** + + +* `\ *Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence*\ , 88 Fed. Reg. 16190 (Mar. 16, 2023) - III `_ +* `\ *Zarya of the Dawn*\ , U.S. Copyright Office (Cancellation Decision, Feb. 21, 2023), Registration No. VAu001480196 - III `_ +* `U.S. Copyright Office, *Copyright and Artificial Intelligence, Part 2: Copyrightability* (Jan. 29, 2025) - III `_ +* `H.R. Rep. No. 94-1476 (1976) - V `_ + +.. _brandolinis-evaluating: + +Evaluating a Reticulum Implementation +------------------------------------- + +.. _brandolinis-intention-of-guide: + +The Intention Of This Guide +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Very few user of network infrastructure can verify the software they run. This is true of the reference implementation as well, and it is precisely why it was engineered the way it was: the entire Reticulum protocol implementation - the transport logic, the cryptographic interfaces, the routing - is less than 15,000 lines of code, including its extensive comments and detailed logging. The reference is *designed* to be readable by a human in a reasonable sitting. That is a deliberate decision, and it is the standard against which every other implementation should be measured: An implementation that asks for trust while being structurally unreadable is asking for the absurd. + +Because most users cannot verify the code directly, the evaluation of the *project* is the evaluation of the software. The framework below exists so that this evaluation can be performed in minutes, by anyone, without expertise - and so that each new "implementation" does not require the kind of full investigation that would otherwise be if not impossible, prohibitevly expensive. + +.. _brandolinis-two-questions: + +Two Questions That Resolve Most Cases +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Other considerations in this guide is further corroboration. These two questions allow you to decide the case quickly in most instances, and they should be asked first. + +**Question 1: Does this speak the protocol, or was it just generated from the reference?** + +The copyright and license realities, described in :ref:`What The Reticulum License Is`, is the legal foundation of this distinction. The protocol is public domain: A *genuine* :ref:`clean-room` implementation, reasoned out and written by humans, is free and welcome, and owes nothing to any license. But an implementation that was *directly generated from* the reference - reproduced by a copy process, whether manually or through a machine or software - is a derivative of the licensed work, and is subject to both the license's conditions, and to the ordinary copyright law examined in :ref:`Copyright & The Two Legal Layers`. A primarily machine-generated copy without substantial human creative input is not merely unlicensed; it is a copyright violation that would exist under any license at all. + +**Ask**: Does the project say where its protocol knowledge came from? Does it credit the reference implementation, or claim "ground-up" status while its own history shows continuous ingestion of the reference's source? Does its license carry the original copyright notice? The answers tell you, within minutes, which of two very different kinds of project you are dealing with. + +**Question 2: Who, or what, is the agent of the work?** + +This distinction, established in :ref:`Assistance Versus Machine Substitution`, is the trust foundation of everything else. Is there a human who decided what to build, judged what was correct, rejected what was wrong, understands what was shipped - and can answer for it, line by line and decision by decision, *without machine assistance*\ ? Or is the machine the agent, with the human's role reduced to the name, the account, and the signature? + +.. + + This test has a sharper form: **would the project be meaningfully different if someone else had pressed the button?** If the answer is no - if any person could have been the signature and nothing would change - then the "author" is not the agent of the work. They are its facade, and the project is, in the most literal sense, worthless and unowned. + +A project with no owner is a project no one can answer for, and infrastructure with no one to answer for it has no place carrying other people's traffic. + +.. _brandolinis-other-signals: + +Other Signals To Look For +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Once the first two questions are answered, the following signals determine the verdict. None is alone decisive; together they form a pattern that is difficult to fake in the directions that matter. + +.. _brandolinis-provenance: + +Provenance and attribution +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* **Credit to the reference.** Does the project name Reticulum's reference implementation + in its README, its website, its licenses, and the code? Does it present itself as a port + or as a "ground-up" origin story? Absence of credit, in a field where every implementation + owes its existence to the reference, is not an oversight; it is a decision. +* **License compliance.** For a derivative, the license conditions apply: the copyright + notice and permission notice in all copies and substantial portions, the harm condition, + the AI-training condition. A project whose license file claims a fresh copyright in the + operator's name, over work that was generated from the reference, has failed the minimum + bar of honesty before any code is read. +* **Disclosed provenance.** Is the use of machine assistance stated openly, or does the + project maintain machinery to conceal it - commit hooks that refuse attribution of + generation, contribution policies that declare machine output the human's own, scrubbers + for personal traces, fictitious contributor identities? The first is the mark of a human + using a tool. The second is the mark of a record being manufactured. +* **The author's history.** Is there a prior record - projects, contributions, a body of + work that a person can look at and reasonably assess? A sudden, fully-formed "decade of experience" + appearing from nowhere, attached to a project of unprecedented scope, is a story that + contradicts itself. + +.. _brandolinis-agency: + +Agency and answerability +~~~~~~~~~~~~~~~~~~~~~~~~ + +* **Who answers the questions?** When technical questions are asked, does a human answer + with substance - going deeper, explaining trade-offs, admitting uncertainty - or do + answers deflect to process ("the CI verifies it", "the proofs prove it", "the audit + covered it")? Are the answers themself machine generated? Deflection to process is + the substitute's answer pattern: It names the machinery instead of the reasoning. +* **Velocity commensurate with authorship.** Is the output volume compatible with human + authorship, review, and judgment? An implementation ten (or 42!) times the size of the reference, + produced in a fraction of the time by a single person, is not evidence of brilliance; it + is evidence of unchecked generation. Churn is part of the same signal: A project that + deletes half of everything it adds is not building; it is looping. +* **Signs of development, growth and learning.** Do reversals exist? Contested decisions? + "We tried X and it was wrong, so we did Y"? Humans change their minds, admit mistakes, and + leave the wear of judgment in their history. Pure generation shows "the polish of its + absence": uniform register, endless renaming, and errors discovered by the generator's own + later runs, recorded as if they were planned milestones. +* **Standing behind failures.** When something is wrong, does the human say "I chose this, + here is what I got wrong, here is the fix"? Or do corrections arrive as process language, + with nobody accepting that a decision was even made? A project whose history contains no + first-person acceptance of error contains no author. + +.. _brandolinis-engineering: + +Engineering reality +~~~~~~~~~~~~~~~~~~~ + +* **Honest benchmarks, or none.** If performance is claimed, is the baseline real - stock, + current, interpreted RNS, on the modern interface, at equal policy, with methodology + published in advance and reproducible by anyone? +* **Interop with reality.** Is compatibility verified against the *current* reference + implementation - on real hardware, including the radio and serial interfaces this + protocol family lives on - in both directions, over long transfers, uptimes and edge cases? +* **The readability standard.** Can a competent human read the core of this implementation + in a reasonable sitting, the way the 15,000-line reference can be read? Was human + readability a stated design goal, or an afterthought? A project that cannot be inspected + is a project asking for trust it has not earned and will never attend to. +* **Nonstandard inventions.** Does the project "improve" on the protocol with its own + modes - new channel behaviour on shared spectrum, new rendezvous mechanisms, new crypto, + "post-quantum" replacements, "turbo" variants? Inventions that change behaviour on a + shared network are not features; they are forks of the airwaves, imposed on every other + node that shares the medium. A project that invents on top of a protocol it has not yet + correctly implemented is not advanced; it is dangerous to its neighbours. +* **The public record.** The commit history is public. Read it. + +.. _brandolinis-network-citizenship: + +Network citizenship +~~~~~~~~~~~~~~~~~~~ + +* **Honest presence.** Does the project identify itself honestly on the network, or does + it masquerade as something it is not? +* **Coexistence.** Does it respect the shared medium and network conventions? A node that + is a bad neighbour on the spectrum is a hazard regardless of how well its code works in isolation. +* **Community participation.** Does the author participate in the community as a member - + answering questions, contributing, learning - or only appear to advertise? The second is + not participation; it is exploiting the community as a broadcasting target. + +.. _brandolinis-signals: + +Monetary and influence signals +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* **Money under the claim.** Donations, funding, or commercial offers premised on claims + like "89× faster" or "formally proven" convert false marketing into a different category + of problem. When money changes hands on the strength of fabricated measurements, the + stakes are no longer theoretical. +* **Tokens and "investment" vehicles.** Any implementation that surrounds itself with a + crypto token, a "coin", or an investment pitch should be treated as what it is: A project + whose primary purpose is to earn the controller a profit, not open networking. +* **Marketing-first ordering.** A polished website on day three, a twelve-language marketing + presence, a "benchmarks" page and a "get started" funnel existing before the protocol works + is a massive red flag. Real builders ship, then talk. The inverse order is the signature of + a project whose goal is attention. + +.. _brandolinis-conformal-surface: + +The Conformal Surface +^^^^^^^^^^^^^^^^^^^^^ + +One warning before the synthesis. When you evaluate any project, assume - as a working hypothesis - that its surface is an investment. The marketing, the design, the badge collection, the "proof records", the fluent and confident prose: This is exactly where substitution invests, for the simple reason that it is where the audience looks first. Fluency is the *minimal conformal surface* of understanding, and the surface is not evidence of anything except that the author *wanted to look convincing*. If you find yourself impressed by the surface before you have asked Question 1 and Question 2, you are doing the evaluation in the order the substitute operator hoped you would. + +.. _brandolinis-possible-verdicts: + +Possible Verdicts +^^^^^^^^^^^^^^^^^ + +The framework proposed here can yield three different verdicts: + +#. + **Meets the standard.** A named human who can answer for the work and demonstrably does; + provenance disclosed; attribution given; honest benchmarks; interop + demonstrated against current, real RNS on real media; readable code; a maintenance + history that shows growth and learning. This standard is not high. It is what the + reference implementation has met, in public, for over a decade, and it is what any + project that wants other people's traffic should be willing to meet in turn. + +#. + **Experimental, but honest.** A project that clearly labels itself as in-progress and + experimental ("do not use this yet", in plain words, as the first thing a user sees) + discloses its provenance, credits the reference, and is being developed in the open by + humans who answer questions. Such projects should be encouraged. They are how the + ecosystem grows, new ideas are tested, and the framework above is designed to make an + honest experimental project *easy* to recognize, not hard. + +#. + **Does not meet the standard.** Unanswerable authorship, concealed provenance, fabricated + measurements, invented protocol behaviour, absent interop, marketing ahead of substance. + Such projects should be treated as unproven regardless of their surface, and as hazards + if they invite users onto shared networks. The community owes them exactly the + skepticism they have earned, and not a moment of engagement beyond that; the network's + time is better spent elsewhere. + +.. _brandolinis-standards-reasonable: + +These Standards Are Reasonable +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +I'll close this guide by stating what these standards are *not*\ : They are neither a demand for perfection, nor a ban on machine assistance. Assistance is useful, when it is used to arrive at *higher levels of synthesis* than unaided work. It is not a requirement that an implementation be a clone of the reference; neither is it a requirement that it invents everything from scratch or aspires to be a :ref:`"clean-room"` implementation. Good implementations of the protocol are very welcome, *however they come*, but working on one requires *serious* work, considerable skill, and **deep competence**. + +The reference implementation has met this standard for years, and its users know what that looks like. + +.. _brandolinis-movement-of-a-dozen: + +The Movement Of A Dozen +----------------------- + +.. _brandolinis-presentation-elongated: + +Presentation, Elongated +^^^^^^^^^^^^^^^^^^^^^^^ + +Whenever Reticulum defends itself, its license, or its community - or simply continues to exist - a familiar chorus appears. The register is always similar: *concern*. Concern about the direction of the project. Concern about its license. Concern about its governance. Concern about its "bullying" of "good-faith contributors". Concern about the future of the ecosystem at the hands of a single maintainer. The chorus speaks in the plural, presents itself as a body of independent voices, and insists, with some frequency, that it is... *not alone*. + +The implicit claim under examination in this section is that there exists a *movement* of concerned individuals, spread across the ecosystem, all worried about Reticulum, and therefore (for some reason) deserving of a place at the table of decisions. + +A resolution of this claim requires one step: Count them. + +.. _brandolinis-headcount: + +Headcount +^^^^^^^^^ + +This "movement" does have a headcount. It is not in the hundreds, and it is not in the dozens. It is a small number of people who appear, in various combinations and under various names, in the following roles: + +* Creators of the machine-generated "Reticulum implementations" examined in this chapter. +* Creators of articles praising those implementations and lamenting the state of the + reference, its moral shortcomings, its unavailability or lack of something it already has. +* Commenters "defending" the implementations when they are evaluated reasonably and critically, + most often by attempting simply to derail the discussion. +* Critics of the Reticulum License on "open source" grounds. +* "Concerned community members" objecting to the maintainer's conduct. +* Campaigners on online platforms; and +* In some cases, a single individual performing *several* of these roles at once, under + different names, in the same week. + +The overlap is well documented at this point, across time and different platforms. The same phrasing, the same arguments, the same links, the same reactive reflexes, the same handful of accounts appearing in the same threads at the same moments. When the sockpuppets are unmasked (and they frequently unmask themselves) the cast does not grow, but rapidly shrinks. + +This is the most interesting single fact about the "movement": **It isn't one. It is a synthetic cast**, held together mostly by LLM-glue, reddit handles and hysteria. A cast is not a constituency. It performs; it does not represent. The difference matters quite a bit, because a great deal of this "movement's" imagined power comes from the assumption that the *plural form* is actual evidence of plurality. If that sentence seemed opaque, notice how many times a statement or article uses "we" instead of "I", and it will be less so. + +.. _brandolinis-recycled-wine: + +Recycled Wine, Fermenting +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The cast is not only small, it is also, by any evidentiary standard, *forgetful*. Every major claim this "movement" advances has been advanced before, answered in public, with evidence, and often years ago - and is then advanced again, unchanged and completely ignoring any rationale or evidence presented previously (to the same people), as if the answer had never been written. + +* **The license argument.** Reticulum is "not really open source" because its license is not + approved by a particular orthodoxy. This is answered (now in a new and updated version, for the + fifth time) in full in :ref:`Open Source Means Open Source`. It was also + answered in public, at length, at the time of the license change - including the + arithmetic of who is actually restricted by which license. It is repeated *ad infinitum* anyway. + Quite a conversation starter, apparently. +* **The distribution argument.** Reticulum is "not properly distributed" because it is not + packaged as a ``.deb`` or on some favoured catalogue. Reality: It is available on practically every + platform with a single command, packaged by the community in a wide range of channels, and + capable of updating itself over its own network. The argument has been answered; it is repeated. +* **The "stepped back" narrative.** When the primary mirror of the project moved away from + a public internet platform, it was spun as the founder leaving for good, or now taking on dictatorial + powers, or abandoning his creation, or any variation or nonsensical combination thereof. + Those spins always center around justifying that *a vaccuum now needs to be filled*. + There was no such vaccuum. The narrative is repeated in various forms whenever convenient. +* **The enclosure narrative.** The license is reframed as a "power grab" or an "enclosure" + of the commons - as if a license whose protocol is public domain and whose conditions + restrict only harm and appropriation were a form of enclosure. The `most recent `_ (and mostly incoherent) + expression of this narrative is, once again, fluent, polite, and factually hollow. The + bizarre arguments supporting the "article" include: Defunct and abandoned forks presented + as living, community forks bearing the very Reticulum License mislabeled as AGPL license vehicles + (created by "concerned users"), companion app forks correctly retaining the Creative Commons + licensing used as further evidence of the same and completely abandoned projects propped up + as being "the ecosystem". Another case of LLM generated nonsense that the "author" didn't bother checking. + The intent is clear here, simply produce more *mass* of the bullshit, so it can be further + referenced, regurgitated and linked to. +* **The "bullying" narrative.** Whenever the community declines to treat manufactured + controversies as legitimate, or calmly documents the falsity of claims, or (Lord forbid) + moves a forum post for violating clearly stated forum rules, + the response is the same: The documentation is "bullying", the community is "excluding" people, the + maintainer is "unprofessional". In the most recent example, those accusations were made by someone who, in the + same week, publically called for the Reticulum maintainer's "removal from the equation", forged a moderator's + username, attempted to drag unrelated individuals into the campaign, and presented a new + round of outright falsehoods. Contrary to popular belief, the accusation of incivility + is not the last resort of the wronged; it is the standard reflex of the exposed. + +None of the "arguments" engages the answers given repeatedly, and extensively. That is the point, and the strategy. The arguments are not produced for the purpose of being engaged; they are produced for the purpose of *being repeated* - the same wine, poured into new bottles, on a cycle. Each cycle is short, cheap to produce, and (thanks to freely available fluent text generation) now nearly effortless. The intended audience is not the community, which has heard it all before. The intended audience is the newcomer, who has not. + +.. _brandolinis-the-method: + +The Method of Madness +^^^^^^^^^^^^^^^^^^^^^ + +The method behind the pattern is consistent and simple enough to be described precisely: + +**Bullshit asymmetry** + +Producing a fluent, plausibly-sourced smear is now the work of minutes. Refuting it to the standard this manual demands is the work of days, and the refuted smear is replaced by the next one within the week. This asymmetry isn't just a fine point of the campaign; **it is the campaign**. The goal is exhaustion - the slow conversion of the community's time and attention from building to defending. + +**Weaponized concern** + +The register of the campaign is almost always the register of solicitude: "we are worried about the ecosystem", "we just want what is best for the community", "this is about the future of the project". The concern is directed, without exception, at the things the campaign wants changed, and the change it wants is always the same: **The replacement of the reference's authority with its own**. Concern is the *costume*\ ; capture is the choreography. It is the oldest form of cheap power grab in the book. + +**Event seizure** + +Any event - a license change, a platform move, a forum moderation decision, a subreddit closure, a security notice, even the most banal messages from maintainers or known contributors - are seized, stripped of their actual context, and re-narrated as evidence of the same pre-written story. The subreddit that was closed after its moderator vanished and ceased moderating (according to *prior agreement with said moderator*) becomes "the maintainer shutting down dissent". Moving away from a highly centralized online platform becomes "the founder retreating". The license becomes "the enclosure". The pattern is so reliable that the story could be pre-written by a lightly mechanized quill; only the date changes. The actual real-world context of these events is documented, in public, in each case; the re-narration proceeds regardless. + +**The legitimacy circuit** + +The campaign invests heavily in the places where legitimacy is minted: Conference talks, blog platforms, social threads, and forums - presented as if these appearances constituted some sort of ecosystem-wide groundswell rather than the same dozen people moving through the same circuit. The LLM-generated articles cite the LLM-generated ports; the ports are praised in the articles; the managers of the ports spread the articles, and echo them on the forums and internet platforms; the conference presentations cite the forums. Random bypassers with the need for a cause watch the conference presentations and take on the holy duty of Internet Soldier. The circuit is closed, self-referential, and (to a reader encountering it fresh) convincing. It is also, entirely, **a loop of bullshit**. + +**The prior-work minefield** + +The machine-generated implementations have a consequence beyond attention: They flood the space with fake "prior work". The effect, as the license discussion predicted in the beginning of 2025, is the creation of a minefield of sloppy repositories that can later be matched against any genuine project, and attempt to claim prior art, or even worse: Dissuade actual, honest developers or builders from taking up a real project they might have succeeded with, because they now believe it has already been done. Just as importantly, it also buries real efforts under machine-generated noise. The machine-ports are not failed attempts to contribute. They are (disregarding intentions, but effectively) the campaign's long game, deployed as inventory. + +.. _brandolinis-fragile-triad: + +A Persistent, But Fragile Triad +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This chapter as a whole has documented three fronts: The legal-ideological attack on the license (:ref:`Open Source Means Open Source`), the substitution and usurpation pattern in machine-generated implementations (:ref:`Assistance Versus Machine Substitution`), and the takeover narratives examined in this section. They are three fronts of the same operation, run by the same cast. + +* The license attack and other urgency-engineered narratives are the *cover*: They supply + the ideological justification for treating the reference as illegitimate, and needing replacement. +* The ports are the *inventory*: they supply the "replacements" that the narrative claims + the ecosystem needs. +* The takeover narrative is the *objective function*: the repeated, persistent, escalating claim that + the reference should be replaced, and that the speakers themself are the natural heirs. + +Each front depends on the others, and all three depend on a single, fragile assumption: That their audience cannot count. Restore the count, and the charade collapses into what it is: + +**A small group of people, obsessively orbiting a technology they did not build, synthetically producing the +appearance of a constituency they do not have, in service of a takeover they cannot justify.** + +.. _brandolinis-pattern-is-not: + +What The Pattern Is Not +^^^^^^^^^^^^^^^^^^^^^^^ + +It is important, to also say what this pattern is *not*, exactly because the campaign depends on being mistaken for such things. + +**It is not criticism** + +The Reticulum community has always had lively, rigorous criticism - of decisions, of priorities, of direction - and it has always engaged that criticism on the merits, and changed course and development priorities many times. The license discussions at the time of the change were extensive, public, and answered in full, including with the critics themselves. Core protocol decisions were always discussed and evaluated in the community. The complex coordination and execution of several protocol upgrades between a loosely organised group of developers, node operators and users have succeeded surprisingly fluidly. All of these are success stories that the "critics" **always** ignore. Real criticism engages the content and accepts evidence. The campaign engages nothing. + +**It is not a community** + +Communities *build things*, maintain them, and have skin in the game; long-term users, operators of nodes, authors of real applications, people whose traffic flows through the network every day. A community has a stake. The "movement" only has an agenda. + +**It is not a debate** + +A debate has parties who evaluate arguments and evidence, and as a function of that, the debate moves forward, perpetually. The campaign's arguments, as shown above, are not designed to survive contact with answers, but to be repeated past them. You cannot debate a loop. You can decline to perform for it, though. + +.. _brandolinis-intent-and-consequence: + +Intent & Consequence +^^^^^^^^^^^^^^^^^^^^ + +While it would provide for interesting speculation, we do not need to know what the individuals in the cast *intend*, and this document will not speculate about their inner lives. People may believe their own narratives entirely, or partly, or not at all; **the pattern is the same in any case**, and the pattern is what matters here, since it is the exact thing that has been so insidiously destructive and resource wasting for the actual Reticulum project and community, ever since Reticulum was more widely discovered, popularized, and became a prime target for all sorts of grift known to man. + +The consequences are very real: + +* **Time**. The community's scarcest resource is the attention of skilled people who actually build + and maintain the network. The campaign converts that attention into reactive defence, on a cycle + with no end. +* **Harm**. Hastily machine-generated implementations, marketed as drop-in replacements and carrying + traffic onto shared networks, mislead users and can damage the network and its neighbours. + We, the actual reticulum community, all rely on these networks every day, and it is my belief + that we need to defend them. The fabricated measurements and laundered authorship examined in this chapter are not + editorial embellishments; they are the mechanism by which real users are induced to run + unverified, and often destructive software. +* **Erosion of the currency of trust**. Every manufactured scandal, every fluently polite smear, every + fabricated "movement" debases the currency of trust and degrades it for **everyone**; + including, most of all, the honest projects that come after. This is deep harm, and + it is the primary reason this chapter exists. + +Whatever the intent - profit, control, attention, or a simple, obsessive inability to stop - the mechanism is the same, and the response should be *calibrated to the mechanism as a whole*, not to the individual person acting as the current avatar for it. + +.. _brandolinis-recognition-and-response: + +Recognition & Response +^^^^^^^^^^^^^^^^^^^^^^ + +For anyone who encounters the pattern fresh, here is a proposal on how to recognise it, and what to do about it. + +**Recognition:** The pattern is recognisable in minutes, once the signs are known: + +* Claims that have been answered before, repeated as if never answered. +* The register of solemn concern applied, without exception, in one direction. +* A severe allergic reaction to answering any questions posed. +* A cast that is small, overlapping, and frequently anonymous, with the *plural form* doing the + work of plurality. +* Sockpuppet theater: The same person or footsoldiers thereof appearing as several "supporters" + (and occasionally slipping up mid-performance). +* Articles, ports, and forum threads that cite and reference each other in a closed loop. +* The immediate, reflexive turn to "bullying", "exclusion" and "toxicity" whenever a claim is refuted. +* A complete absence of engagement with the substance of the answers given, and a complete + absence of stake in the network itself. + +**Response:** A constructive response is one that is proportionate, and does not cost the +community its resources, sanity and dignity: + +* Engage the content once, on its merits (if any), with evidence, in public, and then refer to the + existing records. The answers already exist; they do not need to be re-derived for every new + bottle of piss-sour burgundy served from a man behind the curtains. I will do my best to keep this + chapter up to date with such answers and records, for easy reference, but other great resources + exist. +* Do not become part of the theater performance. The "movement" feeds on engagement in *any* form; + attention is its fuel, and outrage is as good as endorsement for them, if not better. +* Do the headcount. When the audience is reminded that a "movement" is a dozen people + recycling answered falsehoods, its projected power dissipates. The power was never real; + only the audience's own assumption of scale can make the illusion effective. A polished-looking + "ground up" implementation might look like the work of many people, but is most likely + just the result of an LLM looping on a laptop for a couple of months (this is weird, but it is + the reality we now live in). Four different users suddenly singing in unison may look like the + representatives of a broader sentiment, but is most likely the same person hiding behind the same keyboard. +* Then, spend the saved time on the networks: On building real infrastructure, putting up nodes + and antennas, on real development, real maintenance, real coexistence, and on the people + *who actually use Reticulum*. The things that we can only do *together*, as humans. That is + what the fake "movement" cannot do, no matter how fluent and smooth its productions become. + +.. _brandolinis-health-and-coexistence: + +Network Health & Coexistence +---------------------------- + +.. _brandolinis-substance: + +Substance Of The Networks +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Before examining health, we should consider what is being protected. The networks are not a repository. They are not a website, a social presence, or a set of marketing pages. They are a habitat: A living commons of communication, carried by, from a catious estimate, an intermesh now consisting of over a hundred thousand physical devices, embedded in a plethora of applications and packages, transporting terabytes of traffic every single day - real messages, real coordination, real people - across radios, serial lines, phones, laptops, and backbone servers, in cities, places and ways that no other network reaches. + +The protocol belongs to humanity; no one owns it. The network belongs to everyone on it, and its membership is defined by nothing other than participation: A node on a mast, a phone in a pocket, a server routing for its neighbourhood, a developer building on the commons. The network has no gatekeepers because it needs none; it is held together by the same physics and mathematics everywhere, and by a shared expectation of how members behave. That expectation - unwritten, unenforced by any central authority, and just as important as any code - is the subject of this section. The *Zen of Reticulum* calls the software a habitat. A habitat is healthy or unhealthy as a whole, and the health of this one is decided, every day, by the people who live in it. + +.. _brandolinis-property-of-the-whole: + +Health Is A Property Of The Whole +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A network is not made healthy by the excellence of any single part. It is made healthy by the behaviour of every part on the shared medium, and how they interact. And the shared medium is the point. When your node transmits, it transmits into the same spectrum, the same line, the same time, the same mathematical address space, the same bandwidth that its neighbours depend on. + +The network cannot be certified by any single project's claims. A node that is a bad neighbour, that invents its own channel behaviour on shared spectrum, that announces without discipline, that spawns tens of thousands of links to scrape the network, that floods and retries without mercy, is a hazard to every node that shares its medium, regardless of how well its "creator" imagines its own code to work in isolation. + +On a shared medium, "my software works" is not a complete sentence. The complete sentence is "my software works *and coexists*". A network's health deteriorates with its worst-behaved member, and every member has a responsibility to not be *that* member. There is no final, technical solution for this; the solutions are human. + +.. _brandolinis-history-of-what-works: + +A History Of What Works +^^^^^^^^^^^^^^^^^^^^^^^ + +Let's recall, because it is the ground truth this entire thing rests on, that the coexistence model has *worked* - is working, right now, **at scale**. Reticulum's protocol decisions have been discussed and evaluated in the community, openly, for years. Protocol upgrades have been designed, coordinated, and executed between a loosely organised group of independent developers, node operators, and users - and have succeeded, repeatedly, without any corporate board, without any central command, and without the collapse that the skeptics predict every second week (while screaming for *GOVERNANCE*). The reference implementation has been developed in the open for over a decade, by a maintainer who answers for it, fixes bugs or issues within hours of their discovery, and is set down in code deliberately kept small enough (the entire protocol implementation under 15,000 lines, including its comments) for a human to read, verify, *and challenge*. + +This is the empirical baseline that every narrative examined in :ref:`A Movement Of A Dozen` conveniently ignores, in order to justify: + +* The claim that the project is a one-man dictatorship +* The claim that the community is excluded +* The claim that the networks need saving from their own founders + +The **reality**, documented and reproducible, is that a loose community of humans coordinates complex technical evolution *without* the apparatus the narratives insist is missing. The health of the networks is not a promise for the future; it is a demonstrated property of the past and present, under the leadership and community model that brought it into existence and navigated it through difficult decisions and situations over a decade. **My job is to keep it that way**, and you can be damned certain that I take it seriously. + +.. _brandolinis-role-of-the-individual: + +The Role Of The Individual +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The networks are built by physical acts and human coordination. You cannot prompt an antenna into existence. No model can string up a dipole, or stand in the rain aligning a radio, or coordinate with a neighbour three valleys away about who covers which repeater frequency, or sit down with a newcomer and explain why their first node didn't announce. These are the acts that make a network *organic* - present in the physical world, resilient because it is *real*, valuable because it is *human*. The machines and technology we use are tools aimed at a well-defined, openly described goal. But the networks themself are composed of intentional human actions, and every node operator is infrastructure for other humans. + +This has a corollary for the individual: You do not need permission, and you do not need to be an expert, to participate. Run a node. Help a neighbour. Ask questions in the community, and answer the questions you can. Build something small at first. The network grows by these acts, and they are the most meaningful ones - the things that can only be done together, as humans, in the physical world. The parasitic "movement" that haunts the peripheries of this ecosystem cannot do any of this. It cannot build a node because it does not exist, in any real connected and human sense; only people can, and people are precisely what a self-recurrent loop lacks. + +.. _brandolinis-place-of-new: + +The Place Of New Implementations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The future of the network includes more implementations - and they are welcome. This chapter is not an argument against implementing Reticulum. The protocol is public domain, by design, and the network is made stronger by genuine diversity: More *good* implementations, honestly made, mean more resilience, more experimentation, more people who understand the protocol deeply *because they have built it themselves*. That is the goal: **For people to understand and own the technology they rely on**. Not to spew out 600,000 line rust ports that fills no meaningful gap or purpose. + +What the ecosystem needs, from every implementation, is the ordinary floor that :ref:`Evaluating A Reticulum Implementation` establishes, and that the reference has met for over a decade: A human who made it and answers for it; provenance disclosed; attribution given; benchmarks honest or absent; interop demonstrated against the real network; code a human can read. And it needs the one thing that costs nothing and changes everything: **Honest labeling**. + +An experimental implementation that says, plainly, as the first thing a user sees: "This is in-progress, experimental, do not depend on it yet, but help if you can", that is a gift to the ecosystem. It contributes, it invites participation, and it protects users. + +The opposite, the polished "drop-in replacement", does damage far beyond its own users: It dissuades the honest developers who might have built *the real thing*, because the polished slop persuades them the work is already done. That dissuasion is one of the quietest and most expensive harms in this entire affair, and the antidote is honesty at every project's door. + +.. _brandolinis-expanding-commons: + +Expanding The Commons +^^^^^^^^^^^^^^^^^^^^^ + +Coexistence, reduced to its essentials, is a short formula; the duties of membership in a network no one owns: + +* **Be honest.** Say what you are, what you built, how you built it, and what you used to + build it. Label experimental work as experimental. Credit the work you build on, including + the reference implementation, in the licenses and in the prose. Concealment is not a + defence; it is a very clear diagnosis marker. +* **Be owned.** Have a human who made the work and can answer for it. Use assistance, don't + substitute. Never sign what you cannot answer for. The chain of accountability is the + community's only verification at scale, and every link in it is a *person*, not a facade. +* **Be a good neighbour.** Respect the shared mediums. Do not invent new behaviour in our + shared space and call it progress. The network belongs to its other members as much as + to you. +* **Verify against the network.** Compatibility is a property demonstrated with actual nodes, + on actual media, against the actual current protocol, over a period of *years*, not 48 hours. + And not a claim pinned to an old snapshot over loopback. +* **Participate as a member.** Ask, answer, help, build. *Advertising at* the community is not + the same as being part of it, and it is **not** the first thing you should do. + +None of this is a high bar. It is the bar the reference implementation has met, in public, for over a decade, and the bar the ecosystem has adopted organically itself, successfully, through every protocol upgrade it has ever coordinated, and everything running on Reticulum today, that people actually use. It is not a new requirement; it is the existing, working culture of the networks, now written down so that newcomers can find it and so that those who would exploit us cannot claim they never saw it. + +.. _brandolinis-defence-of-commons: + +Defence Of The Commons +^^^^^^^^^^^^^^^^^^^^^^ + +The networks need defending - not because they are under severe physical attacks (yet), but because attention, talent and resources is being stolen from them, trust is being mined against them, and its newcomers are being harvested by the machinery documented in this chapter. Defence, for a commons, has specific shapes, and it is not what the theater would like it to be. + +* Defence is **documentation**: Records kept public, of what was claimed, what was + answered, and what turned out true. +* Defence is **a headcount**: Calm, unexcited reminders that a "movement" might just be a dozen + people having a tantrum. +* Defence is **honesty in action**: The visible, ordinary practice of the good behaviour + by the people who actually run the networks. +* And defence is **building**: Every node raised, every page of *real* documentation, every + honest implementation, every new user helped into the community with the knowledge to know + what they are doing is more durable than any rebuttal, because it adds to the thing being + defended. + +---- + +**The theatre cannot keep up with a network.** + +**It can only orbit it, while it recycles its own sour piss.** + +---- + +A lot of us rely on these networks every day. They carry our messages, our coordination, our friendships, and in some places, our safety. That is exactly why they are a target: + +They are valuable, free, and very hard to shut down. The response is not to become aggressive. It is to be *more* of what the network already is: Real, open, owned, and shared. + +*Mark* + +.. _brandolinis-prns: + +Addendum A: The Prns Case +------------------------- + +.. _brandolinis-purpose-and-scope: + +Purpose & Scope +^^^^^^^^^^^^^^^ + +This section provides a concrete example, which future evaluations can use as a template. Its purpose is not to be the last word on this particular subject, but to be an example of how the ideas in this chapter can be applied, and to make the next such examination easier. + +The subject of this case study is **Prns**, a project published at the repository ``github.com/KenAKAFrosty/Prns``, presented as a "ground-up implementation of Reticulum, written in Rust", marketed as faster, safer, and more strictly tested than the reference, widely promoted with the claim of "up to 89× the throughput" of the reference implementation, and an "author" actively engaged in the tactics described in :ref:`A Movement Of A Dozen` on online platforms. The record described below is the project's own, and sourced from its GitHub repository, analyzed locally. + +.. _brandolinis-project-in-brief: + +The Project In Brief +^^^^^^^^^^^^^^^^^^^^ + +* **Time span.** 3,374 commits between 2026-05-26 and 2026-09-12: approximately 110 days, + at a mean rate of ~31 commits per day. Monthly: 132 / 1,137 / 1,097 / 805 / 203. +* **Authorship.** 3,252 of 3,374 commits (96.4%) are authored by a single account. A + second identity, "Prns Tests tests@example.test" - a fictitious identity on a reserved + domain - contributed 35 commits, every one of them website and marketing content. +* **Size.** 3,519 tracked files; 1,983 Rust files; 636,226 lines of Rust; approximately + 22.7 MB of Rust source; 69.5 MB of total repository content. +* **Scope claimed.** A daemon ("drop-in replacement" for the reference daemon), embedded + firmware for three microcontroller families (including six ESP32-S3 board variants and + nRF52840), SDKs and bindings for nine languages, a browser-based node and web flasher, a + twelve-language website, a benchmark apparatus with its own publication and "proof" + pipeline, and a validation hub with oracles, fuzzing, mutation testing, and formal-proof + claims. +* **Marketing claims.** "Ground-up implementation of Reticulum"; "up to 89× the + throughput"; "48× smaller peak-memory footprint"; "33× the energy efficiency"; + "Measured, not just claimed"; "Enforced, then audited"; "byte-for-byte wire parity with + the reference implementation"; "works with Sideband, NomadNet, MeshChat, etc."; + "no_std (no alloc required either)". +* **Status at the time of writing.** Version 0.3.7; published version history begins at + 0.3.0. The repository continues to receive commits. + +.. _brandolinis-prns-question-1: + +Question 1: Is this a clean implementation, or was it directly generated from the reference? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The first of the two deciding questions from :ref:`Evaluating A Reticulum Implementation` is settled by the project's own record. An actual :ref:`clean-room` implementation, reasoned out and written by humans, would owe nothing to any license. The data available shows clearly that Prns is not that. + +* **The founding state.** The first commit, "Scaffold Personal Reticulum suite", contains + the scaffolding of not one but two ports - ``personal-rns`` and ``personal-lxmf``\ , the latter + being the reference's companion messaging protocol - together with a daemon scaffold and + a 233-line founding document, ``docs/build-ethos.md``. That document declares the project's + goal as a "performance-focused drop-in-replacement for rnsd" and its governing principle + as: "Port the contract, not the implementation." It further states directly to the + machine-loop, that **"You owe the reference fidelity at exactly two boundaries: + The wire... The behavior. ... Between those two boundaries, the model is yours"**. + At this point, the very first commit, effectively the whole of the implementation design + and any relevant decisions are handed over to the LLM. +* **Continuous ingestion from the reference.** 506 commits reference RNS or Reticulum + source behaviour; the word "parity" appears in 49 commit messages. Commits cite the reference + implementation's own source locations (for example ``Transport.py:1367``) when correcting + their own divergences and mistakes. +* **Byte-level fidelity as an explicit goal.** Within 48 hours of the first commit, the + record shows a "crypto adapter - vetted primitives, byte-exact vs RNS 1.3.1", and a wire + implementation matching the reference's packet header layout. The project's own + validation apparatus decodes wire vectors using the reference implementation's own + packet parser, and the interop suite consists of real, stock-RNS peer nodes - that is, + the reference source itself, used as the ground truth against which this LLM output is + checked, and committed as accepted and verified after 48 hours of the project's recorded start. +* **The marketing mismatch.** The same record that documents all of the above describes the + project, publicly, as "a ground-up implementation of Reticulum" - while declining, on its + website, to link to the reference implementation at all: the entire tree mentions the + reference's author in six files, and the website in none. + +Conclusion: the project's own history and commit record establishes that it was generated directly from the reference implementation's source code, not reasoned out from the public-domain protocol. It is a derivative of licensed work within the meaning of :ref:`the Reticulum License` and :ref:`general copyright law`. The "ground-up" claim, which carries its entire legal and marketing posture, is disproven by the project's own history. + +.. _brandolinis-prns-question-2: + +Question 2: Who, or what, is the agent of the work? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The second deciding question is answered by the application of :ref:`Assistance Versus Machine Substitution` criteria to the project. + +**Scope that no human could have authored** + +636,226 lines of Rust in 110 days is approximately 5,800 lines per day, every day, including weekends - with 149 commits recorded between midnight and 06:00, and Saturday the single busiest weekday. No human review or decision capacity is commensurable with this volume; the review capacity and the output volume are structurally incommensurable, which is the definition of unauthored scope. + +**Uniform generation** + +The record shows no sign of human development, growth, or learning: No contested decisions, no style drift. Instead: endless renaming (in the first 48 hours: ``State → EngineState → TickInput → TickOutput``\ ), uniform fluent register in every commit, and the exact same, synthetic voice in code, documentation, and website copy. + +**Discovery by regeneration** + +Corrections arrived by the machine's own subsequent runs, recorded as planned milestones. In early July 2026, a series of "core review" commits documented, in the project's own words: + +* announce-ID history "was unbounded per-slot growth" (\ ``54cc8d601``\ ); +* interface announce limiting could "leak a sustained flood" (\ ``9d27af75c``\ ); +* a "phantom-airtime leak" where frames "used to vanish silently" (\ ``4ed75ffdd``\ ); +* Group-packet deduplication "which RNS does not do" - a behaviour the reference never had, + implemented and later removed (\ ``edd8e72be``\ ); +* "both ``unwrap_or(&[])`` arms were unreachable dead defaults" (\ ``74bea355e``\ ); +* a benchmark crate "hasn't compiled since" a prior rename, undetected for weeks because it + was outside the CI's workspace (\ ``86240b027``\ ). + +Earlier still: the record shows a ">1 MiB RNS-to-Prns interop stall" closed three weeks in +(\ ``cc4d524a3``\ ), and a known send-path hang shipped with the note "typed fast-fail a +candidate for later" (\ ``a010e6613``\ ). + +**Laundered provenance** + +The repository contains a committed commit-message hook (\ ``.githooks/commit-msg``\ ) that *blocks* any commit containing attribution for machine generation ("generated with claude/codex/copilot/cursor/gemini", "co-authored-by"), with the explanation "The committer owns the commit". The contributing guide is explicit: "AI tools ... are welcome ... what you submit is *yours*", and describes the contributing population as "both human and automated contributors". The fictitious "Prns Tests" identity completes the picture: A manufactured, unknowable contributor, used for marketing content. + +**Authorship by assignment** + +The human whose name is on the work cannot answer for it, because the choices were never made by a human, and only the general shape and constraints of the outward presentation was. Nothing in the project's history shows an individual explaining a design decision, accepting a mistake in the first person, or going deeper under technical questioning; the record shows process language and marketing instead. Per the earlier mentioned test: any other person could have pressed the same button, and nothing would be different. The project is effectively unowned, and void of value. + +By the criteria of :ref:`Assistance Versus Machine Substitution`, this is substitution. The machine was the agent of the work; the "author" was a facade. + +.. _brandolinis-prns-performance: + +The performance claims +^^^^^^^^^^^^^^^^^^^^^^ + +The project's central marketing claim - "up to 89× the throughput" of the reference - is also its most completely documented failure, because the project published the evidence of its own measurement. The apparatus, the results, and the problems are all on the record. + +**The claim** + +The README states "up to 89× the throughput"; the on-network marketing page repeats "up to 89× the throughput, 48× smaller peak-memory footprint, and 33× the energy efficiency of stock RNS 1.4.2"; the website's front page carries the tagline "Measured, not just claimed". + +**The apparatus** + +The reference is loaded through ``benchmarks/reference/compiled_reference.py``\ , which installs ``pyximport`` and then asserts two things: that ``RNS.compiled == True``\ , and that at least *one* RNS module was loaded from a native extension. The project's own published "proof" records show exactly what those checks captured, on every platform: + +.. code-block:: + + aarch64-apple-darwin: .../RNS.cpython-313-darwin.so, Cython 3.2.8, Python 3.13.13 + x86_64-unknown-linux-gnu: .../RNS.cpython-313-x86_64-linux-gnu.so, gcc 11.4.0 + x86_64-pc-windows-msvc: ~/.prns-oc/lib.win-amd64-cpython-313/RNS.cp313-win_amd64.pyd + +In every case the recorded native module is the **top-level package only** - ``RNS.so``\ , nothing below it. Nothing named ``RNS.Transport``\ , ``RNS.Destination``\ , ``RNS.Packet``\ , ``RNS.Link``\ , or ``RNS.Resource`` ever appears, because *nothing below the top level was ever compiled*. Nobody bothered to check or verify *anything* here. + +The machine output was simply taken for truth, and a full marketing strategy was spun and produced on it. "RNS 1.4.2 (compiled)" - the label used in every table, chart, and marketing page - *is not a mode of RNS that exists*, but the hallucinations of a machine, which the humans created a marketing strategy on. In reality, it is the old ``CRNS`` development shim, whose top-level-only, debug-oriented "compilation" is slower than plain interpreted RNS, and which was *defunct for over a year* before these benchmarks were published. + +**Interface choices** + +The harness writes the reference's configuration itself (\ ``benchmarks/reference/participant_node.py``\ ): ``TCPClientInterface`` for the initiator, ``TCPServerInterface`` for the responder and both relay sides, with ``UDPInterface`` as the abstract wire. The reference was never given its modern ``BackboneInterface`` on any platform, forcing the slowest possible interrfaces. The interface selection is never mentioned in any methodology text. + +**The policy** + +The published default-policy tables record the asymmetry directly: Prns at 500 Mbps / 128 KiB TCP policy against the reference at 10 Mbps / 8 KiB - slyly footnoted as "preserves each implementation's normal TCP policy" (in the case of RNS, a conservative default policy that was selected to prioritize coexistence on slower, shared links, requiring the user to dial it up to full speed if they knew what they were doing). Raw transport "throughput" ratios of 20.65× (Linux) and 38.84× (Windows) are therefore mostly policy, not engine. + +**The cross-host evidence** + +The published results show the same scenario producing wildly different ratios by host, and the variance is entirely in the reference artifact: + +.. list-table:: + :header-rows: 1 + + * - Host + - Prns, single-packet + - "Reference", single-packet + - Ratio + * - macOS (Apple M4) + - 37.4k/s + - 420/s + - 89.09× + * - Linux (i7-1260P) + - 25.3k/s + - 3.5k/s + - 7.19× + * - Windows (Ryzen 5 5600X) + - 30.8k/s + - 3.9k/s + - 8.00× + +Prns is consistent (25–37k/s). The reference artifact collapses to different depths on different hosts, and the single worst collapse - 420 packets per second on macOS - is the cell selected as the global headline. The "89×" is not a measure of Prns; it is a measure of how badly the broken baseline happened to fail on one host. + +For reality calibration: Stock, interpreted RNS 1.5.4 on an ordinary mid-range laptop, single core, sustains roughly 30,000 single-packet deliveries per second (including ephemeral-key decryption), ~175,000–280,000 packets per second in transit relay, and on the order of 10 Gbps at 16 KiB payloads. The project's "compiled" artifact measured 420–3,900 packets per second for its single-packet scenario: An order of magnitude or more *below* stock interpreted RNS. The comparison being marketed was not "Rust vs Python"; **it was "an implementation running under optimal conditions versus a mislabeled, broken shim on a slow legacy interface at a severe policy disadvantage"**. + +**The equalized rows** + +The project's own "1 Gbps policy" rows, in which both sides are explicitly configured identically, publish ratios of roughly 2.4–8.4× across all hosts and scenarios - still against the broken baseline, but nowhere near 89×, and consistent with the ordinary, uncontroversial observation that a native implementation tends to outperform an interpreted one in raw throughput. That point needed no fudging to make, and is banal. + +Interestingly, though, it seems that Prns is really only *marginally* faster than a Python implementation, running in interpreted mode, on a single CPU core. + +**Assessment** + +The front page says "Measured, not just claimed." The record shows the opposite ordering: claimed, and arranged to look measured. No methodology section anywhere states what "compiled" means, that it is a deprecated development shim, that it builds debug targets, or which interface the reference was given; the one statement of the policy asymmetry appears in a footnote of the results tables themselves. If they did not need to fudge it, they would have published the method clearly. + +.. _brandolinis-prns-overall: + +Overall Evaluation +^^^^^^^^^^^^^^^^^^ + +Evaluated against the conditions of :ref:`Evaluating A Reticulum Implementation`: + +* **Provenance and attribution.** Fails: The fake "ground-up" origin story; zero reference links + on the website; a single well-hidden link in the README; a license file reading + ``Copyright (c) 2026 The Prns Authors`` over work directly generated from the licensed reference; + no original copyright or permission notice anywhere. +* **Agency and answerability.** Fails on every criterion of :ref:`Assistance Versus Machine Substitution`: + Unauthored scope, uniform generation, discovery by regeneration, laundered provenance, + authorship by assignment. +* **Engineering.** Fails: The benchmark apparatus above; interop demonstrated only + against a pinned, outdated reference version over loopback while the marketing claims current + parity, interop failures with stock RNS; vendored prebuilt binaries and a republished fork + of an upstream crate (``nrf-softdevice 0.1.0-prns.1``) with no verifiable provenance; + committed WASM bundles. +* **Network behaviour.** Fails: Invented spectrum behaviour and compatibility claims + about third-party applications of the reference ecosystem (Sideband, NomadNet, MeshChat) + that are not established by any evidence. +* **Monetary and influence signals.** The marketing apparatus - website before protocol, + day-three twelve-language marketing, false benchmark headlines, "audited" and "formal proof" + claims - the conformal surface described in :ref:`Evaluating A Reticulum Implementation`: + is where this project invested. + +.. _brandolinis-prns-licensing: + +Licensing Analysis +^^^^^^^^^^^^^^^^^^ + +Applying the two legal layers established in :ref:`Copyright & The Two Legal Layers`: + +**Layer A - copyright infringement (license-independent)** + +The record shows a direct copy roundtrip: the licensed reference implementation fed into a machine, transformed, at a scale and cadence no human could review, with a license file asserting a fresh copyright in the operator's name and no acknowledgment of the work the project was generated from. No substantial, new human creative input is demonstrated anywhere in the record - the founding document explicitly frames the design as an instructed port of the reference's contract. A primarily machine-generated copy of a copyrighted work, not accompanied by demonstrable substantial human creative input, is a derivative work over which the copier holds no copyright, and a reproduction of which without the original author's permission infringes the original author's copyright. This holds under any license, MIT included. The operator's copyright claim over the result is, on this evidence, not merely unsubstantiated; it is the absence of one, directly asserted in the project's own writing. + +**Layer B - license conditions (Reticulum License specific)** + +Modern Reticulum - the current wire format, the AES-256-based link encryption, ratchets, the cryptographic machinery as it exists today - has been published under the Reticulum License since April 15, 2025, effective from release 0.9.4 and every release since. As a derivative of that work, the license's conditions attach: The copyright and permission notice must be included in all copies and substantial portions; the AI-training condition must be honoured; the harm condition must be honoured. The record shows none of the notice requirements met, and a production process that consists of the licensed work being ingested into a machine and regurgitated, at industrial scale and cadence. + +**The cascading consequence** + +Prns is distributed claiming dual MIT/Apache-2.0 licensing. It is, however, a direct derivative of Reticulum-licensed work, and the claimed grant is therefore void. Every downstream project that builds on Prns believing it is MIT/Apache-licensed is building on a grant that does not exist. The users of Prns, and all software developers using it, have in effect, been placed under conditions they were never told about. The "ground-up" claim is not merely false; it is the sole load-bearing element of an entire licensing posture, and it fails spectacularly. + +.. _brandolinis-prns-consequences: + +Consequences +^^^^^^^^^^^^ + +The consequences of this pattern are examined in the following sections: The harm to users and to the network in :ref:`A Movement Of A Dozen`, and the human dimension in :ref:`Network Health & Coexistence`. The contribution of this addendum is narrower and intended as an instructive example: This is what a substitution project looks like, in full, on its own record. It is a reference example for :ref:`Evaluating A Reticulum Implementation`, and it demonstrates, in one case, most of the elements this chapter describes. + +.. _brandolinis-prns-verdict: + +Verdict +^^^^^^^ + +Applying the three verdicts of :ref:`Evaluating A Reticulum Implementation`, this project does not meet the standard. It is not "experimental but honest" - it is not labeled as experimental anywhere; the first thing users saw was a polished marketing presence promising a finished, tested, drop-in replacement. It is a project whose central claims are fabricated (the performance apparatus), whose provenance is laundered (the authorship machinery), whose foundation is misrepresented (the "ground-up" story), whose core semantics were learned late and by regeneration, and whose operator cannot possibly answer for any of it. It is also a blatant copyright violation of the reference implementation. + +The proposed conclusion, for users and for the network: Treat the Prns project as hostile regardless of its polished surface, and as a hazard insofar as it invites users onto shared networks. Nothing in this section is a judgment about the people involved; it is a reading of the results produced, their history and how they came to be, which in the regrettable lack of any human authorship is the only thing that can be expected to be held to account. + +.. _brandolinis-prns-dating: + +Dating +^^^^^^ + +This examination reflects the publicly available material as of September 2026; the repository in question continued to receive commits at the time of writing, so readers should treat citations to commits and files as point-in-time evidence. A `forensics snapshot `_ is publicly available on GitHub. diff --git a/docs/source/git.rst b/docs/source/git.rst index 6cedd1b0..3699be39 100644 --- a/docs/source/git.rst +++ b/docs/source/git.rst @@ -8,6 +8,16 @@ This chapter of the manual serves as the technical reference for the distributed A set of utilities for distributed collaborative software development and publishing are included in RNS. +.. only:: html + + .. image:: screenshots/rngit.webp + :align: center + +.. only:: latex + + .. image:: screenshots/rngit.png + :align: center + The system consists of two parts: The ``rngit`` node that hosts repositories, and the ``git-remote-rns`` helper that enables Git to communicate with rngit nodes. As soon as you have RNS installed on your system, you can transparently use Git with Reticulum-hosted repositories just like any other type of remote. Git over Reticulum uses URLs in the following format: ``rns://DESTINATION_HASH/group/repo``. If you set a branch to track a Reticulum remote as the default upstream, you can simply use ``git`` as you normally would; all commands work transparently and as expected. @@ -133,6 +143,9 @@ To create a new empty repository on a remote node: This creates a bare Git repository at the specified path. You must have ``create`` permission for the target group. When a repository is created, the creator automatically receives ``adm`` (admin) permissions on the repository through an auto-generated ``.allowed`` file. +.. tip:: + If you want to use a different primary branch name than ``master``, you can change it inside the bare git repository directory with ``git symbolic-ref HEAD refs/heads/name_of_other_branch``. + **All Command-Line Options (rngit create)** .. code:: text @@ -683,6 +696,7 @@ The following template files are supported: - ``commit.mu`` - Individual commit detail page - ``refs.mu`` - Branches and tags listing - ``stats.mu`` - Statistics page +- ``no_ident.mu`` - Displayed to non-identified initiators if blocked Templates can include the following variables: diff --git a/docs/source/graphics/rns_logo_256.webp b/docs/source/graphics/rns_logo_256.webp new file mode 100644 index 00000000..8c2e9196 Binary files /dev/null and b/docs/source/graphics/rns_logo_256.webp differ diff --git a/docs/source/graphics/rns_logo_512.webp b/docs/source/graphics/rns_logo_512.webp new file mode 100644 index 00000000..566a2ff1 Binary files /dev/null and b/docs/source/graphics/rns_logo_512.webp differ diff --git a/docs/source/index.rst b/docs/source/index.rst index d00efa5c..fd305241 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -32,6 +32,7 @@ to participate in the development of Reticulum itself. support examples license + brandolinis .. toctree:: :maxdepth: 2 diff --git a/docs/source/screenshots/columba.png b/docs/source/screenshots/columba.png index 89d85443..b464ca07 100644 Binary files a/docs/source/screenshots/columba.png and b/docs/source/screenshots/columba.png differ diff --git a/docs/source/screenshots/columba.webp b/docs/source/screenshots/columba.webp index 956ea8e4..07ea65ed 100644 Binary files a/docs/source/screenshots/columba.webp and b/docs/source/screenshots/columba.webp differ diff --git a/docs/source/screenshots/meshchatx.png b/docs/source/screenshots/meshchatx.png index 018ec871..6677a0a6 100644 Binary files a/docs/source/screenshots/meshchatx.png and b/docs/source/screenshots/meshchatx.png differ diff --git a/docs/source/screenshots/meshchatx.webp b/docs/source/screenshots/meshchatx.webp index 24fd7ba0..94edb72a 100644 Binary files a/docs/source/screenshots/meshchatx.webp and b/docs/source/screenshots/meshchatx.webp differ diff --git a/docs/source/screenshots/modem73.jpg b/docs/source/screenshots/modem73.jpg new file mode 100644 index 00000000..ca3ebcb5 Binary files /dev/null and b/docs/source/screenshots/modem73.jpg differ diff --git a/docs/source/screenshots/modem73.png b/docs/source/screenshots/modem73.png new file mode 100644 index 00000000..2cec4d1d Binary files /dev/null and b/docs/source/screenshots/modem73.png differ diff --git a/docs/source/screenshots/modem73.webp b/docs/source/screenshots/modem73.webp new file mode 100644 index 00000000..5adadc76 Binary files /dev/null and b/docs/source/screenshots/modem73.webp differ diff --git a/docs/source/screenshots/nomadnet_6.png b/docs/source/screenshots/nomadnet_6.png new file mode 100644 index 00000000..3df866ef Binary files /dev/null and b/docs/source/screenshots/nomadnet_6.png differ diff --git a/docs/source/screenshots/nomadnet_6.webp b/docs/source/screenshots/nomadnet_6.webp new file mode 100644 index 00000000..3f973658 Binary files /dev/null and b/docs/source/screenshots/nomadnet_6.webp differ diff --git a/docs/source/screenshots/partyline.png b/docs/source/screenshots/partyline.png new file mode 100644 index 00000000..16982c6d Binary files /dev/null and b/docs/source/screenshots/partyline.png differ diff --git a/docs/source/screenshots/partyline.webp b/docs/source/screenshots/partyline.webp new file mode 100644 index 00000000..ac7d96c1 Binary files /dev/null and b/docs/source/screenshots/partyline.webp differ diff --git a/docs/source/screenshots/ren_browser.png b/docs/source/screenshots/ren_browser.png new file mode 100644 index 00000000..7737e50a Binary files /dev/null and b/docs/source/screenshots/ren_browser.png differ diff --git a/docs/source/screenshots/ren_browser.webp b/docs/source/screenshots/ren_browser.webp new file mode 100644 index 00000000..6a6223ec Binary files /dev/null and b/docs/source/screenshots/ren_browser.webp differ diff --git a/docs/source/screenshots/rentui.png b/docs/source/screenshots/rentui.png new file mode 100644 index 00000000..6272b4f5 Binary files /dev/null and b/docs/source/screenshots/rentui.png differ diff --git a/docs/source/screenshots/rentui.webp b/docs/source/screenshots/rentui.webp new file mode 100644 index 00000000..0c40fad6 Binary files /dev/null and b/docs/source/screenshots/rentui.webp differ diff --git a/docs/source/screenshots/reticulated.jpg b/docs/source/screenshots/reticulated.jpg new file mode 100644 index 00000000..785622b8 Binary files /dev/null and b/docs/source/screenshots/reticulated.jpg differ diff --git a/docs/source/screenshots/reticulated.webp b/docs/source/screenshots/reticulated.webp new file mode 100644 index 00000000..ebd2a67e Binary files /dev/null and b/docs/source/screenshots/reticulated.webp differ diff --git a/docs/source/screenshots/retipedia.png b/docs/source/screenshots/retipedia.png new file mode 100644 index 00000000..fae27ff6 Binary files /dev/null and b/docs/source/screenshots/retipedia.png differ diff --git a/docs/source/screenshots/retipedia.webp b/docs/source/screenshots/retipedia.webp new file mode 100644 index 00000000..8ffe1a0f Binary files /dev/null and b/docs/source/screenshots/retipedia.webp differ diff --git a/docs/source/screenshots/rngit.png b/docs/source/screenshots/rngit.png new file mode 100644 index 00000000..037b16fc Binary files /dev/null and b/docs/source/screenshots/rngit.png differ diff --git a/docs/source/screenshots/rngit.webp b/docs/source/screenshots/rngit.webp new file mode 100644 index 00000000..5e1f54e4 Binary files /dev/null and b/docs/source/screenshots/rngit.webp differ diff --git a/docs/source/screenshots/rrc.png b/docs/source/screenshots/rrc.png new file mode 100644 index 00000000..21ab31b0 Binary files /dev/null and b/docs/source/screenshots/rrc.png differ diff --git a/docs/source/screenshots/rrc.webp b/docs/source/screenshots/rrc.webp new file mode 100644 index 00000000..56889713 Binary files /dev/null and b/docs/source/screenshots/rrc.webp differ diff --git a/docs/source/software.rst b/docs/source/software.rst index c7314aa1..66315fea 100644 --- a/docs/source/software.rst +++ b/docs/source/software.rst @@ -4,146 +4,225 @@ Programs Using Reticulum ************************ -This chapter provides a non-exhaustive list of notable programs, systems and application-layer -protocols that have been built using Reticulum. +This chapter provides a non-exhaustive list of notable programs, systems and application-layer protocols that have been built using Reticulum. -These programs will let you get a feel for how Reticulum works. Most of them have been designed -to run well even over slow networks based on LoRa or packet radio, but all can also be used over fast -links, such as local WiFi, wired Ethernet, the Internet, or any combination. +Many different applications using Reticulum already exist, serving a wide variety of purposes from day-to-day communication and information sharing to systems administration and tackling advanced networking and communications challenges. -As such, it is easy to get started experimenting, without having to set up any radio -transceivers or infrastructure just to try it out. Launching the programs on separate -devices connected to the same WiFi network is enough to get started, and physical -radio interfaces can then be added later. +.. tip:: + For ease of discovery while reading this manual over the web or as an e-book, links provided in this chapter primarily point to repositories and pages located on internet servers. In many cases, these are public web mirrors, with the upstream repositories residing on Reticulum nodes. For the latest source, updates and information regarding any project, be sure to check their Nomad Network or ``rngit`` nodes. -Programs & Utilities -==================== +These programs will let you get a feel for how Reticulum works. Most of them have been designed to run well even over slow networks based on LoRa or packet radio, but all can also be used over fast links, such as local WiFi, wired Ethernet, the Internet, or any combination. -Many different applications using Reticulum already exist, serving a wide variety of purposes -from day-to-day communication and information sharing to systems administration and tackling -advanced networking and communications challenges. +As such, it is easy to get started experimenting, without having to set up any radio transceivers or infrastructure just to try it out. Launching the programs on separate devices connected to the same WiFi network is enough to get started, and physical radio interfaces can then be added later. -Development of Reticulum-based applications and systems is ongoing, so consider this list -a non-exhaustive starting point of *some* of the options available. With a bit of searching, -primarily over Reticulum itself, you will find many more interesting things. +Development of Reticulum-based applications and systems is ongoing, so consider this list a non-exhaustive starting point of *some* of the options available. With a bit of searching, primarily over Reticulum itself, you will find many more interesting things. -Remote Shell -^^^^^^^^^^^^ +Browsing & Publishing +===================== -The `rnsh `_ program lets you establish fully interactive -remote shell sessions over Reticulum. It also allows you to pipe any program to or from a -remote system, and is similar to how ``ssh`` works. The ``rnsh`` program is very efficient, and -can facilitate fully interactive shell sessions, even over extremely low-bandwidth links, -such as LoRa or packet radio. +In addition to the programs listed in this section, other Nomad Network clients include: -In addition to the default, fully interactive terminal mode, -for extremely limited links, ``rnsh`` offers line-interactive mode, allowing you to interact -with remote systems, even when link throughput is counted in a few hundreds of bits per second. - -.. raw:: latex - - \newpage +- `MeshChatX `_ +- `Columba `_ Nomad Network ^^^^^^^^^^^^^ -The terminal-based program `Nomad Network `_ -provides a complete encrypted communications suite built with Reticulum. It features -encrypted messaging (both direct and delayed-delivery for offline users), file sharing, -and has a built-in text-browser and page server with support for dynamically rendered pages, -user authentication and more. +The terminal-based program `Nomad Network `_ provides a complete encrypted communications suite built with Reticulum. -.. image:: screenshots/nomadnet_3.png - :target: https://github.com/markqvist/nomadnet +.. only:: html -`Nomad Network `_ is a user-facing client -for the messaging and information-sharing protocol LXMF. + .. image:: screenshots/nomadnet_6.webp + :align: center + :target: https://github.com/markqvist/nomadnet + +.. only:: latex + + .. image:: screenshots/nomadnet_6.png + :align: center + :target: https://github.com/markqvist/nomadnet + +It features encrypted LXMF messaging (both direct and delayed-delivery for offline users), file sharing, and has a built-in text-browser and page server with support for dynamically rendered pages, user authentication and more. It also includes an RRC client and a suite of network utilities. + + +Ren Browser +^^^^^^^^^^^ + +`Ren Browser `_ is a modern, standalone browser for Nomad Network using the `Reticulum-Go `_ implementation. The project is actively being developed, and should be considered alpha level software, but much of the functionality is already working. If you want to help expanding the ecosystem, this is an excellent project to take a look at. + +.. only:: html + + .. image:: screenshots/ren_browser.webp + :align: center + :target: https://github.com/fr33n0w/rBrowser + +.. only:: latex + + .. image:: screenshots/ren_browser.png + :align: center + :target: https://github.com/fr33n0w/rBrowser + +Ren Browser is great example of an application aiming for true, seamless interoperability with the existing software ecosystem. It can operate fully standalone using it's own embedded `Go implementation `_ of Reticulum, or seamlessly utilise a shared RNS instance already running on the system. RNS Page Node ^^^^^^^^^^^^^ -`RNS Page Node `_ is a simple way to serve pages and files to any other Nomad Network compatible client. Drop-in replacement for NomadNet nodes that primarily serve pages and files. +`RNS Page Node `_ is a simple way to serve pages and files to any other Nomad Network compatible client. Drop-in replacement for NomadNet nodes that primarily serve pages and files. Retipedia ^^^^^^^^^ -You can host the entirity of Wikipedia (or any ``.zim``) file to other Nomad Network clients using `Retipedia `_. +You can host the entirity of Wikipedia, StackExchange or any other ``.zim`` file, to Nomad Network clients using `Retipedia `_. + +.. only:: html + + .. image:: screenshots/retipedia.webp + :align: center + :target: https://github.com/RFnexus/Retipedia + +.. only:: latex + + .. image:: screenshots/retipedia.png + :align: center + :target: https://github.com/RFnexus/Retipedia + + +Git Over Reticulum +^^^^^^^^^^^^^^^^^^ + +The included :ref:`rngit` system provides a fully distributed solution for managing, hosting, collaborating on and interacting with Git repositories over Reticulum. + +.. only:: html + + .. image:: screenshots/rngit.webp + :align: center + +.. only:: latex + + .. image:: screenshots/rngit.png + :align: center .. raw:: latex \newpage +Messaging & Voice +================= + Sideband ^^^^^^^^ -If you would rather use an LXMF client with a graphical user interface, you can take -a look at `Sideband `_, which is available for Android, -Linux, macOS and Windows. Sideband is an advanced LXMF and LXST client, and a multi-purpose Reticulum -utility, with features and functionality targeted at advanced users. +`Sideband `_ is a technical LXMF and LXST client, for Android, Linux, macOS and Windows. It also serves as a multi-purpose Reticulum utility, with features and functionality targeted at advanced users. .. only:: html .. image:: screenshots/sideband_devices.webp :align: center - :target: https://unsigned.io/sideband + :target: https://github.com/markqvist/Sideband .. only:: latex .. image:: screenshots/sideband_devices.png :align: center - :target: https://unsigned.io/sideband + :target: https://github.com/markqvist/Sideband -Sideband allows you to communicate with other people or LXMF-compatible -systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, Encrypted QR -Paper Messages, or anything else Reticulum supports. +Sideband allows you to communicate with other people or LXMF-compatible systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, Encrypted QR Paper Messages, or anything else Reticulum supports. -It also interoperates with all other LXMF clients, and provides advanced features such as voice messaging, -real-time voice calls, file attachments, private telemetry sharing, and a full -plugin system for expandability. +It interoperates with all other LXMF clients, and provides advanced features such as PTT and voice messaging, real-time voice calls, file attachments, private telemetry sharing, and a full plugin system for expandability. .. raw:: latex \newpage MeshChatX -^^^^^^^^ +^^^^^^^^^ -A `Reticulum MeshChat fork from the future `_, with the goal of providing everything you need for Reticulum, LXMF, and LXST in one beautiful and feature-rich application. This project is separate from the original `Reticulum MeshChat `_ project, and is not affiliated with the original project, but is a much more up-to-date, comprehensive and well-maintained fork. +`MeshChatX `_ is an all-in-one Reticulum client with messaging, calling, and a NomadNet browser, providing everything you need for Reticulum, LXMF, and LXST in one beautiful and feature-rich application. .. only:: html .. image:: screenshots/meshchatx.webp :align: center - :target: https://git.quad4.io/RNS-Things/MeshChatX + :target: https://meshchatx.com/ .. only:: latex .. image:: screenshots/meshchatx.png :align: center - :target: https://git.quad4.io/RNS-Things/MeshChatX + :target: https://meshchatx.com/ -Features include full LXST support, custom voicemail, phonebook, contact sharing, and ringtone support, multi-identity handling, modern UI/UX, offline documentation, expanded tools, page archiving, integrated maps, telemetry and improved application security. +Features include full LXST support, custom voicemail, phonebook, contact sharing, ringtone support, multi-identity handling, modern UI/UX, offline documentation, expanded tools, page archiving, integrated maps, telemetry and improved application security. -.. raw:: latex +Columba +^^^^^^^ - \newpage +`Columba `_ is a simple and familiar LXMF messaging app Android, built with a native Android interface and Material Design 3. It also includes LXST voice call functionality, and a mobile Nomad Network page browser. + +.. only:: html + + .. image:: screenshots/columba.webp + :align: center + :target: https://github.com/torlando-tech/columba/ + +.. only:: latex + + .. image:: screenshots/columba.png + :align: center + :target: https://github.com/torlando-tech/columba/ + + +Ren TUI +^^^^^^^ + +`Ren TUI `_ is an early prototype terminal LXMF client for Reticulum built with Odin on librns (Reticulum-Go). It aims for NomadNet-like messaging/browsing without urwid or ncurses. + +.. only:: html + + .. image:: screenshots/rentui.webp + :align: center + :target: https://github.com/Quad4-Software/Ren-TUI + +.. only:: latex + + .. image:: screenshots/rentui.png + :align: center + :target: https://github.com/Quad4-Software/Ren-TUI + +Chat +==== Reticulum Relay Chat ^^^^^^^^^^^^^^^^^^^^ `Reticulum Relay Chat `_ is a live chat system built on top of the Reticulum Network Stack. It exists to let people talk to each other in real time over Reticulum without dragging in message databases, synchronization engines, or architectural commitments they did not ask for. -The `rrcd `_ program provides a functional, reference RRC hub-server daemon implementation. RRC user clients include `rrc-gui `_ and `rrc-web `_. +.. only:: html + + .. image:: screenshots/rrc.webp + :align: center + +.. only:: latex + + .. image:: screenshots/rrc.png + :align: center RRC is closer in spirit to IRC than to modern “everything platforms.” You connect, you join a room, you talk, and then you leave. If you were present, you saw the conversation. If you were not, the conversation did not wait for you. This is not an accident. This is the entire design. +The `rrcd `_ program provides a functional, reference RRC hub-server daemon implementation. RRC user clients include: + +- `Nomad Network `_ +- `MeshChatX `_ +- `Eridanus `_ +- `rrc-gui `_ +- `rrc-web `_ + RetiBBS ^^^^^^^ -`RetiBBS `_ is a bulletin board system implementation for Reticulum networks. +`RetiBBS `_ is an old-school bulletin board system implementation for Reticulum networks. .. only:: html @@ -163,29 +242,14 @@ RetiBBS allows users to communicate through message boards in a secure manner. \newpage -RBrowser -^^^^^^^^ +Voice & Telephony +================= -The `rBrowser `_ program is a cross-platform, standalone, web-based browser for exploring NomadNetwork Nodes over Reticulum Network. It automatically discovers NomadNet nodes through network announces and provides a user-friendly interface for browsing distributed content with Micron markup support. +In addition to the programs listed in this section, other LXST voice clients include: -.. only:: html - - .. image:: screenshots/rbrowser.webp - :align: center - :target: https://github.com/fr33n0w/rBrowser - -.. only:: latex - - .. image:: screenshots/rbrowser.png - :align: center - :target: https://github.com/fr33n0w/rBrowser - -Includes useful features like automatic listening for announce, adding nodes to favorites, browsing and rendering any kind of NomadNet links, downloading files from remote nodes, a unique local NomadNet Search Engine and more. - - -.. raw:: latex - - \newpage +- `Sideband `_ +- `MeshChatX `_ +- `Columba `_ Reticulum Network Telephone ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,14 +270,31 @@ The ``rnphone`` program, included as part of the `LXST `_ is a group voice application for Reticulum, built on `LXST `_, inspired by `Mumble `_. + +.. only:: html + + .. image:: screenshots/partyline.webp + :align: center + :target: https://github.com/markqvist/LXST + +.. only:: latex + + .. image:: screenshots/partyline.png + :align: center + :target: https://github.com/markqvist/LXST + +It provides both realtime group voice over any Reticulum transport capable of >6 kilobits per second, LXST dial-in support, listen-only music/broadcasting rooms, and many other useful functions. + LXST Phone ^^^^^^^^^^ -The `LXST Phone `_ program is a cross-platform desktop application for performing LXST voice calls over Reticulum. +The `LXST Phone `_ program is a cross-platform desktop application for performing LXST voice calls over Reticulum. It supports various advanced features such as SAS verification, peer blocking, rate limiting, encrypted call history storage and contact management. .. only:: html @@ -227,28 +308,60 @@ The `LXST Phone `_ program is a cross-plat :align: center :target: https://github.com/kc1awv/lxst_phone -It supports various advanced features such as SAS verification, peer blocking, rate limiting, encrypted call history storage and contact management. - .. raw:: latex \newpage -LXMFy -^^^^^ +System Administration +===================== -`LXMFy `_ is a comprehensive and advanced bot creation framework for LXMF, that allows building any kind of automation or bot system running over LXMF and Reticulum. `Bot implementations exist `_ for Home Assistant control, LLM integrations, and various other purposes. +Remote Shell +^^^^^^^^^^^^ +The included :ref:`rnsh` program lets you establish fully interactive +remote shell sessions over Reticulum. It also allows you to pipe any program to or from a +remote system, and is similar to how ``ssh`` works. The ``rnsh`` program is very efficient, and +can facilitate fully interactive shell sessions, even over extremely low-bandwidth links, +such as LoRa or packet radio. -LXMF Interactive Client -^^^^^^^^^^^^^^^^^^^^^^^ - -`LXMF Interactive Client `_ is a feature-rich, terminal-based LXMF messaging client with many advanced features and an extensible plugin architecture. +In addition to the default, fully interactive terminal mode, for extremely limited links, +``rnsh`` offers line-interactive mode, allowing you to interact with remote systems, even +when link throughput is counted in a few hundreds of bits per second. RNS FileSync ^^^^^^^^^^^^ -The `RNS FileSync `_ program enables automatic file synchronization between devices without requiring central servers, internet connectivity, or cloud services. It works over any network medium supported by Reticulum, including radio, LoRa, WiFi, or the internet, making it ideal for off-grid, privacy-focused, and resilient file sharing. +The `RNS FileSync `_ program enables automatic file synchronization between devices without requiring central servers, internet connectivity, or cloud services. It works over any network medium supported by Reticulum, including radio, LoRa, WiFi, or the internet, making it ideal for off-grid, privacy-focused, and resilient file sharing. + +.. raw:: latex + + \newpage + +Utilities & Components +====================== + +Modem73 +^^^^^^^ + +`MODEM73 `_ and its companion `Modem73Interface `_ is an open source software modem that works with any HF, VHF, or UHF radio capable of 2400 Hz of bandwidth. All you need is a sound card and audio cable for your radio. + +.. only:: html + + .. image:: screenshots/modem73.webp + :align: center + :target: https://github.com/RFnexus/modem73 + +.. only:: latex + + .. image:: screenshots/modem73.jpg + :align: center + :target: https://github.com/RFnexus/modem73 + +LXMFy +^^^^^ + +`LXMFy `_ is a comprehensive and advanced bot creation framework for LXMF, that allows building any kind of automation or bot system running over LXMF and Reticulum. `Bot implementations exist `_ for Home Assistant control, LLM integrations, and various other purposes. Micron Parser JS @@ -256,6 +369,25 @@ Micron Parser JS `Micron Parser JS `_ is the JavaScript-based parser for the Micron markup language, that most web-based Nomad Network browsers use. If you want to make utilities or tools that display Micron pages, this library is essential. +Reticulated +^^^^^^^^^^^ + +`Reticulated `_ is a Reticulum Network simulator that spawns live, interactive Reticulum instances controllable from a node-based Web UI. + +.. only:: html + + .. image:: screenshots/reticulated.webp + :align: center + :target: https://github.com/RFnexus/Reticulated + +.. only:: latex + + .. image:: screenshots/reticulated.jpg + :align: center + :target: https://github.com/RFnexus/Reticulated + +You can create networks of any topology and set bitrate, MTU, and configure path loss and propagation behavior. It provides a top-down view to a live network. You can connect any Reticulum application to the simulated network. It also has built in utilities like a basic LXMF chat function and Resource transfer included. + RNMon ^^^^^ @@ -267,6 +399,16 @@ RNMon \newpage +Device Flashers +=============== + +In addition to the included command-line ``rnodeconf`` flasher, several community-provided RNode device flashers exist: + +- `RNS Moscow `_ +- `Aetherlab `_ + +Several programs, such as `Sideband `_ and `MeshChatX `_ also include built-in device flashers that can be used fully offline. + Protocols ========= @@ -298,8 +440,8 @@ Interface Modules & Connectivity Resources This section provides a list of various community-provided interface modules, guides and resources for creating Reticulum networks over special or challenging mediums. -* Custom interface module for running `RNS over HTTP `_ +* `Modem73 `_ is an efficient software modem that can be used with Reticulum +* Custom interface module for running `RNS over HTTP `_ * Guide for running `Reticulum over ICMP `_ using ``PipeInterface`` * Guide for running `Reticulum over DNS `_ with Iodine -* Guide for running `Reticulum over HF radio `_ -* `Modem73 `_ is a KISS TNC OFDM modem frontend that can be used with Reticulum \ No newline at end of file +* Guide for running `Reticulum over HF radio `_ \ No newline at end of file diff --git a/docs/source/support.rst b/docs/source/support.rst index 39bcf8f3..011f1231 100644 --- a/docs/source/support.rst +++ b/docs/source/support.rst @@ -28,9 +28,6 @@ Donations are gratefully accepted via the following channels: Ko-Fi: https://ko-fi.com/markqvist -Are certain features in the development roadmap are important to you or your -organisation? Make them a reality quickly by sponsoring their implementation. - .. raw:: latex \newpage diff --git a/docs/source/using.rst b/docs/source/using.rst index a61c2b30..c31ce7dd 100644 --- a/docs/source/using.rst +++ b/docs/source/using.rst @@ -274,8 +274,7 @@ You can easily add ``rnsd`` as an always-on service by :ref:`configuring a servi The rnstatus Utility ==================== -Using the ``rnstatus`` utility, you can view the status of configured Reticulum -interfaces, similar to the ``ifconfig`` program. +Using the ``rnstatus`` utility, you can view the status of and control configured Reticulum interfaces, similar to the ``ifconfig`` program. **Usage Examples** @@ -350,6 +349,9 @@ Filter output to only show some interfaces: -h, --help show this help message and exit --config CONFIG path to alternative Reticulum config directory --version show program's version number and exit + --attach name Attach interface by name + --detach name Detach interface by name + --reload name Reload interface by name -a, --all show all interfaces -A, --announce-stats show announce stats -P, --pr-stats show path request stats @@ -367,6 +369,8 @@ Filter output to only show some interfaces: -w seconds timeout before giving up on remote queries -d, --discovered list discovered interfaces -D show details and config entries for discovered interfaces + --show-stale show stale discovery entries + --show-unknown show discovery entries without version info -m, --monitor continuously monitor status -I, --monitor-interval seconds refresh interval for monitor mode (default: 1) @@ -705,7 +709,7 @@ The rnx Utility The ``rnx`` utility is a basic remote command execution program. It allows you to execute commands on remote systems over Reticulum, and to view returned command output. For a fully interactive remote shell solution, be sure to also take a look -at the `rnsh `_ program. +at the :ref:`rnsh` program. **Usage Examples** @@ -771,6 +775,8 @@ another one, which will be created if it does not already exist --version show program's version number and exit +.. _using-rnsh: + The rnsh Utility ================ @@ -1230,6 +1236,8 @@ For more fine-grained control over how discovered interfaces are auto-connected, * The ``autoconnect_announces_to_internal`` option allows you to specify that auto-connected interfaces should propagate announces to ``internal`` mode interfaces, even if the auto-connected interface's mode would normally not allow for this. +* The ``autoconnect_unverified_implementations`` option will allow the interface discovery system to auto-connect to *any* announced interface, even those coming from unverified, experimental or potentially broken implementations. Be very careful with this option. + Remote Management ----------------- diff --git a/setup.py b/setup.py index 8e7dd5a6..68556b3c 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ if '--pure' in sys.argv: if '--native' in sys.argv: native_build = True sys.argv.remove('--native') - print("Building native (compiled) wheel") + print("Building native wheel") exec(open("RNS/_version.py", "r").read()) with open("README.md", "r") as fh: @@ -50,6 +50,7 @@ NATIVE_EXCLUDES = { "RNS.Interfaces.AX25KISSInterface", "RNS.Utilities.rngit.main", "RNS.Utilities.rngit.pages", "RNS.Utilities.rngit.server", + "RNS.Utilities.rngit.media", "RNS.Utilities.rngit.util", "RNS.Utilities.rnsh._version", "RNS.Utilities.rnsh.args", diff --git a/tests/coalesced_transmit.py b/tests/coalesced_transmit.py index c3dda4e8..b1e026e4 100644 --- a/tests/coalesced_transmit.py +++ b/tests/coalesced_transmit.py @@ -1,3 +1,5 @@ +# Partially generated with lc/kimi_k2.6 +# Reviewed and approved by Mark Qvist import unittest import os diff --git a/tests/egress.py b/tests/egress.py index 5d0adecc..86c86824 100644 --- a/tests/egress.py +++ b/tests/egress.py @@ -1,3 +1,5 @@ +# Partially generated with lc/kimi_k2.6 +# Reviewed and approved by Mark Qvist import unittest import time diff --git a/tests/hdlc.py b/tests/hdlc.py index 6352341d..585b1dff 100644 --- a/tests/hdlc.py +++ b/tests/hdlc.py @@ -1,3 +1,5 @@ +# Partially generated with lc/kimi_k2.6 +# Reviewed and approved by Mark Qvist import unittest import os diff --git a/tests/hkdf.py b/tests/hkdf.py index 087cb6dc..e77f4a2e 100644 --- a/tests/hkdf.py +++ b/tests/hkdf.py @@ -1,3 +1,5 @@ +# Partially generated with lc/kimi_k2.6 +# Reviewed and approved by Mark Qvist import unittest import os diff --git a/tests/ifac.py b/tests/ifac.py index 48db799d..27e41933 100644 --- a/tests/ifac.py +++ b/tests/ifac.py @@ -1,3 +1,5 @@ +# Partially generated with lc/kimi_k2.6 +# Reviewed and approved by Mark Qvist import unittest import os diff --git a/tests/throughput.py b/tests/throughput.py index 34e623cf..2ec6757a 100644 --- a/tests/throughput.py +++ b/tests/throughput.py @@ -1,5 +1,8 @@ #!/usr/bin/env python3 # +# Generated with lc/deepseek_v4_flash_q8_k_xl +# Reviewed and corrected by Mark Qvist +# # Usage examples: # # python3 tests/transport_throughput.py