Trust model
Installing noomoo in a repository does not make that repository trusted. A repository can carry its own configuration, and that configuration can name JavaScript modules to run. The check of the repository state can also reach the network. noomoo therefore runs project code and calls out only in a repository that you agreed to, and it keeps that agreement on your machine, not in the repository.
Where the consent lives
The consent is a list of repositories in trusted-repos.json, in the user settings directory: ~/.config/noomoo, or the directory named by NOOMOO_CONFIG_DIR. Each entry is the real path of the repository root, with symbolic links resolved. The file is not in the repository on purpose: a file inside the repository could have been put there by the repository itself, and that would cancel the boundary. Only the setup commands write to it: setup --yes, init, doctor --fix and, to remove an entry, rollback --yes. The repository root is the directory you run the command in, not the top of the git tree, so run the commands from the root of the repository.
Granting and revoking
| Action | Command | Effect on the consent |
|---|---|---|
| Grant | npx noomoo setup --yes | Adds the repository to the list. |
| Grant | npx noomoo init | The same as setup --yes. |
| Grant | npx noomoo doctor --fix | Also adds the repository, because it deploys the same skeleton. It writes the setup manifest as well, so rollback undoes what it did and removes the entry. |
| Revoke | npx noomoo rollback --yes | Removes the repository from the list, together with the rest of the installation. |
| Replace in CI | NOOMOO_TRUST_PROJECT=1 | Every repository counts as consented to. CI has no user settings directory, so the owner of the pipeline sets the variable. |
npx noomoo setup without --yes prints the plan, including the line about the consent, and writes nothing. The plugin does not grant consent either; see Plugin.
What does not happen without consent
| Without consent | What noomoo does instead |
|---|---|
stages | The stages of config/pipeline.json are modules of the repository. They are not loaded, and the run prints how many it skipped and why. The stages of noomoo itself run. |
doctor | It does not call gh to ask how merges are configured; the item says that the repository is not trusted. |
rollback --yes | It refuses and prints how to grant the consent. A plan without --yes is still printed. |
plugin hook | The hook of the plugin exits without reading the event or starting any process until the repository has both the setup manifest and your consent. |
git, gh, claude | They are not taken from the repository. noomoo drops the repository's folders and every node_modules/.bin from PATH. On Windows, where a launch by name looks in the working folder before PATH, noomoo starts them by the absolute path found in the cleaned PATH, and only a .com or .exe file, as a launch by name without a shell would. After consent, a launch from the repository's folders starts them by name, as before. |
The other commands run when you invoke them, in any repository. The consent decides whether code that the repository supplies may run, not whether a command you typed may run.
The manifest is an untrusted input
setup records what it did in .noomoo/setup-manifest.json, inside the repository, and rollback reads it. A file in the repository could have been written by the repository, so rollback treats the manifest as untrusted: it checks every path and every git config key before it touches anything. The rules are listed in What setup changes.
Reporting a problem
A way around this boundary is exactly the kind of problem the security policy asks you to report. For what noomoo writes and where it connects, see Data and network.