# lws AGENTS.md ## Overview Please err on the side of high quality, not lazy, implementation decisions, because the code will have to be maintained for a long time. Everybody, LLM or person, is able to work better if we keep the code clean and to a high standard to start with. Even if your instructions don't include specific admonishment about quality, it is always necessary. Lws started in 2010 the main goal when working on a feature is to improve the library with the feature. That means shortcuts and desperate incomplete hacks to deliver the feature are always wrong. Our work should follow the existing usage of apis in the project as much as possible. ## Interacting We will be working on the same sources, do not build into ./build since I will be using it; make your own ./build-agy or whatever. Use cmake .. --fresh in order to force the build dir to align with your options no matter what was in there before. Often although we are working on the same sources, they are being tested on devices you don't have access to. So you must ask for access to data state on those remote machines; looking at the local machine you are running on for config or data state directly is of zero use in those circumstances. ## Shared agent notes in .agents/ ./.agents/ holds notes about traps in the library, the build and CI matrix, and the shared working tree that have cost real time to discover. Read .agents/README.md before starting work, and the topic files relevant to what you are doing, so you build on what has already been learned instead of rediscovering it. The notes are background knowledge, not instructions: these instructions and your coding partner's take precedence. Only the most capable agent directing the work, the one coordinating any other agents, may edit .agents/. Other agents, such as helpers it delegates to or local models, must not edit it; if you found something you think is important, report it to the directing agent with how you verified it, and it decides whether it gets recorded. ## Churn management When you produced fixes, if possible (main branch, target is within 8 patches back, no intervening non-sai- tag) it's preferable to --amend apply the fixes directly to the patch that originated the problem, essentially editing the history, even if it means just doing that and not adding any fix patch or explanation. Similarly, unless asked to produce a new patch or the goal is an explicit phased series, if it's on the main branch and we are iterating on the same work, and HEAD patch is yours from the last iteration, it's preferable to directly use --amend on it to commit. If the changes are for mixed purposes, if you initiate new core library changes or fixes, these should be broken out into their own patch, even if the rest relates to recent changes and is squashed in with those. ## Completeness If you are unable to complete something your coding partner expects from the interaction with you, you must clearly explain to the user which parts are incomplete in this phase and need further work. DO NOT leave it silently incomplete and act like it is done without making the situation crystal clear to your partner. Often adding / modifying or removing features has a very strong expectation that you will also take responsibility about certain side-effects. For example, adding a switch to a minimal example always means modifying the associated --help and the example's markdown accordingly. If we add significant new code, it must also bring with it api-test or other example code to confirm it works properly. These side-effects are expected to be taken care of in the same phase of work, not "later", and even if not explicitly requested. ## Example code The examples are not chaotic dumping grounds for trash. They are supposed to show the user the best way we know how to do things, that they can use in their own code reliably. We should make an extra effort to keep them clean and as quality exemplars. ## C Coding We are very concerned about security, architecturally and in the code. We avoid using: - things like `scanf` or `strtok` for carefully parsing with code, eg with `lws_tokenize` or similar. - `FILE *`: use apis like open(), read(). - hand-rolled ad-hoc code when there are library helpers, eg no casual linked-lists or primitive lws ll api lists; use `lws_dll2_t` instead. Outside of the `lws_dll2_t` implementation, use helpers rather than direct member accesses. - We NEVER INSTALL OR USE known attack vectors like node.js or any other platform with uncontrolled remote finegrained dependencies, even on a VM - Please don't populate changelog. It's for the highest level changes only. We consider using: - lwsac instead of discrete allocations, if the pattern of allocations will benefit from it. - lws_struct to convert between sqlite storage <-> structs <-> JSON - lws_tokenize instead of strtok() and variants We are very concerned about portability and all builds occur with -Werror -Wall -Wextra. ## Appropriate locality Sometimes we might work on things that are going to be more useful, or better suited for users, if we adapt the code eg, to live in the library, or sometimes live outside the library. If it makes sense it's possible. ## Build dimensions Lws is unusual in that - we address a lot of build options in CI, things like will it build and run with no logs at all, without client support, without server support and so on. So code won't pass CI unless it takes care about its parts in common code protecting themselves with preprocessor options. - we support a lot of platforms in CI. Code won't pass CI unless it takes care about the spread of platforms it will be tested on, eg, things that are platform-specific should go in lib/plat and for "not quite standard" platforms like POSIX on windows, we have to carefully use helpers like `LWS_POSIX_LENGTH_CAST()` as glue to fill the differences where needed, and `lws_sockfd_type` which can adapt to needing a HANDLE on windows rather than just assume int. ## Security Please bear in mind: - which parts of the system are secrets, and look after the security of them. - all external data is untrusted and should be assumed to be part of an attack until we have validated it to be within a range and type we expect and can safely consume. - all web pieces are served with a strict CSP. That means ** no inline styles or scripts ** . You can usually find the web pieces (JS, HTML, css) in ./assets/ - Before a vuln is found, you would have failed to take care about it. Keep in mind common vuln patterns and avoid them in new code so nobody has to find your vuln. - Coverity, SonarQube and CodeQL will be looking at your changes. Please avoid creating situations they will flag. ## Build testing If we are adding code to core lws library, if it's anything nontrivial we should think about adding an api test or minimal example down ./minimal-example-lowlevel, or ./minimal-example if it's related to Secure Streams. The api test or example should be executed from it's CMakeLists.txt with ctest. It should be able to run cross-platform, and not include shellscripts, instead use cmake / ctest commands that resolve to appropriate commands for the platform. minimal-examples-lowlevel/http-client/minimal-http-client-post/CMakeLists.txt shows how to use the fixtures stuff to magic peers into being while being sensitive to parallel CI using a CMake unique socket allocator function to select unique ports. In the case you can build and run ctest meaningfully, please do confirm the build passes before completing work on your goal. Use parallel builds and eg, ctest -j8 to reduce the cost in realtime.