# contributing to mycelium thanks for your interest in contributing to Mycelium, an alleged "operating system"! please bear in mind that this is a hobby project that i work on in my spare time, so pull requests may not always be reviewed in a timely manner. ## AI policy when contributing to Mycelium, an alleged "operating system", you are free to use any tools you deem appropriate. this includes the LLM of your choosing, agents, loops, gastown, AI code review tools, Amazon Rufus, or even `vim`. however, all contributions to this project (including my own) must abide by exactly one rule: **your code (and any associated prose, such as commit messages and documentation) must not _look_ like it was written by a large language model.** basically, the game is simple: contributors are free to use whatever AI tools they wish when contributing to mycelium and associated projects, but in order to have your PRs merged, you have to be able to *trick me* into believing it was written by a human being. any PRs which appear to have been generated by a model will be closed as a violation of the Mycelium AI Policy (even if they were actually written on pencil and paper by a human being in a cave with no access to the internet). repeated violations of the Mycelium AI Policy may result in a ban from contributing to the repo. ### advice on AI policy compliance + when using an AI coding agent, the easiest way to ensure your contributions are compliant with the Mycelium AI Policy is to read the code that the model generates, and rewrite any parts of it that "feels like Claude-babble". repeat this process as needed until it no longer feels like it was written by a model. + you may feel that it is possible to prompt an LLM into outputting code that doesn't look model-generated. my personal experience has been that this is impossible, and model-written code always requires some degree of rewriting to make it look Normal. if you think you're better at prompting than me, you are welcome to try it, but...good luck! + while contributors are free to disclose the use of AI tools in their pull requests, note that this will put you at a substantial disadvantage, because an AI disclosure will mean I go in suspicious. if you can trick me into believing that a pull request which says "This code was written using Claude" was written entirely by an organic, free-range human being...well, I'll be impressed. ### rationale the Mycelium AI Policy may, at first blush, seem a bit strange: why am I explicitly *encouraging* potential contributors to attempt to mislead a maintainer? and, doesn't the "you have to trick me" policy seem a bit... adversarial? to answer some of these questions, allow me to share some of the thinking behind the Mycelium AI Policy, and why I believe it is the best way to achieve *my personal goals* for this project. 1. this project is a labor of love. I am doing this purely for fun, in my spare time. reviewing thousands of lines of slop is not particularly fun. reading the bizarre blend of Rationalist slang, technical jargon, and nonsensical metaphors that Claude's comments always seem to regress into is particularly infuriating and I don't ever want to see it in my weekend project. 3. I believe that code can be beautiful. I love code which is both technically effective *and* a form of creative self-expression. I want the code in Mycelium to be beautiful. and I have never found purely model-generated code to be beautiful. 4. however, I have also found LLMs to be an effective tool for generating large amounts of code faster than a human being can type it. i have also found them to be useful tools in applications where the model is *not* writing the code: while an LLM review may not question the high-level design of a feature the way a human reviewer would, they *are* remarkably thorough, and good at finding the one place where you forgot to change something or didn't use checked arithmetic or whatever. i don't want to completely forbid the use of a tool which i *have* found useful in some particular, restricted ways. 5. i don't want to merge code that is not well-understood by a human being. i do not believe that it is possible for an engineer to take responsibility for code that they do not understand thoroughly. in LLM-assisted programming, there is an obvious temptation to not read the code that the model generates. we can all fall victim to this temptation from time to time. in my own work, i have found that the act of rewriting the model-generated code to not Look Like That forces the person who generated it to actually read and understand it thoroughly. 6. it's my project and I can do whatever the hell I want to. ## building & running mycelium is built using [`inoculate`], the horrible mycelium build tool. `inoculate` automates the process of compiling the kernel and bootloader and producing a bootable mycelium disk image. it also provides a test runner for running kernel-mode tests in [QEMU], running the release kernel in [QEMU], and launching a [`gdb`] debugging session. ```text inoculate 0.1.0 the horrible mycelium build tool (because that's a thing we have to have now apparently!) USAGE: inoculate [OPTIONS] [SUBCOMMAND] FLAGS: -h, --help Prints help information -V, --version Prints version information OPTIONS: --bootloader-manifest The path to the `bootloader` crate's Cargo manifest. If this is not provided, it will be located automatically --color Whether to emit colors in output [env: CARGO_TERM_COLORS=] [default: auto] [possible values: auto, always, never] --kernel-manifest The path to the kernel's Cargo manifest. If this is not provided, it will be located automatically -l, --log Configures build logging [env: RUST_LOG=] [default: warn] -o, --out-dir Overrides the directory in which to build the output image -t, --target-dir Overrides the target directory for the kernel build ARGS: The path to the kernel binary SUBCOMMANDS: help Prints this message or the help of the given subcommand(s) run Builds a bootable disk image and runs it in QEMU (implies: `build`) test Builds a bootable disk image with tests enabled, and runs the tests in QEMU ``` [`inoculate`]: https://github.com/hawkw/mycelium/tree/main/inoculate ### cargo aliases the following [cargo aliases] are provided for development: - `cargo inoculate` runs any `inoculate` subcommand - `cargo run-x64` runs the x86_64 kernel in [QEMU] - `cargo test-x64` runs the x86_64 kernel's kernel-mode test suite in [QEMU] - `cargo build-x64` builds the x86_64 bootable disk image - `cargo clippy-x64` runs the [clippy] linter with the kernel x86_64 target enabled (rather than the build host's target triple). [cargo aliases]: https://github.com/hawkw/mycelium/blob/main/.cargo/config [clippy]: https://github.com/rust-lang/rust-clippy ### justfile in addition to `inoculate`, which is used to build and run the kernel, a `justfile` for the [Just] command runner is provided to automate testing and linting workflows that involve multiple steps. note that any recipe that takes a `` can be invoked with the name of a specific crate in the workspace, or without a crate name to run that recipe for the whole Mycelium workspace. - `just preflight`: runs all tests and checks. recommended for running on a branch prior to opening a pull request. - `just test `: runs all tests for `` (or the whole workspace if no crate is provided), including host tests, [Loom] tests, [Miri] tests, and doctests. - `just miri `: runs tests for `` in the [Miri] interpreter. - `just loom `: runs [Loom] models for `` (or all [Loom] models in the workspace). - `just test-host `: runs standard `cargo test` tests (host tests) for `` (or the whole workspace). - `just test-kernel`: runs the kernel test suite in [QEMU] --- this is equivalent to `cargo test-x64`. - `just docs `: builds and opens development RustDoc documentation for `` (or for the whole workspace). - `just lint `: runs [clippy] and [rustfmt] linting checks for ``/the whole workspace. running `just --list` (or just `just`) will print a list of all available `just` recipes. see for more information on using [Just]. [Miri]: https://github.com/rust-lang/miri [Loom]: https://crates.io/crates/loom [rustfmt]: https://github.com/rust-lang/rustfmt ### build dependencies to build mycelium for x86_64, you need the following: - a nightly rust compiler - the `rust-src` and `llvm-tools-preview` Rust toolchain components the `rust-src` and `llvm-tools-preview` toolchain components are required in the [`rust-toolchain.toml`] file, so in most cases, rustup will install them automatically. if, for whatever reason, they are not present, you can install them manually with: ```shell rustup component add rust-src llvm-tools-preview ``` [`rust-toolchain.toml`]: https://github.com/hawkw/mycelium/blob/main/rust-toolchain.toml ### runtime dependencies & tools to run the mycelium kernel-mode tests, or to run an interactive mycelium session using `inoculate`, you need the [QEMU] emulator; in particular, `qemu-system-x86_64` to run the x86_64 mycelium kernel. you can install QEMU using your favorite package manager. similarly, to use `inoculate`'s support for [`gdb`] (the GNU debugger), you need `gdb` installed on your system. it's probably also possible to debug mycelium with `lldb` somehow, but i haven't tried that. in order to use the [`justfile`], you need the [Just] command runner. this is optional, but useful to have. most of the Just recipes run tests using [`cargo nextest`] rather than `cargo test`, but the [`justfile`] will offer to install [`cargo nextest`] for you if needed. for NixOS users, there's an included [`shell.nix`] which can be used with [`nix-shell`] or [`direnv`]. this should ensure all required runtime dependencies and tools are present. for users of other package managers, you're on your own...but if there's a similar mechanism for installing the required dev tooling for a project from a config file, i'd welcome a PR to add support for your preferred package manager. [QEMU]: https://www.qemu.org/ [`gdb`]: https://www.gnu.org/software/gdb/ [`shell.nix`]: https://github.com/hawkw/mycelium/blob/main/shell.nix [`nix-shell`]: https://nixos.wiki/wiki/Development_environment_with_nix-shell [`direnv`]: https://direnv.net/ [`cargo nextest`]: https://nextest.sh [`justfile`]: #justfile [Just]: https://just.systems