Every settings field declares its tier; a value in the wrong file is an error naming
file, key and tier. A field naming a program or affecting a gate cannot be declared
instance. Secrets are references only: {"ref": "<name>"} via WIKITOOL_SECRET_<NAME> or
a user-only secrets file, {"ref": "op://..."} via op read (locked 1Password: exit 42).
The preflight records op as an optional tool. doctor gains one line per tier, docs
verify checks a committed wikitool.json for plaintext secrets, CI resolves a real
op:// value through 1password/load-secrets-action. No feature reads its settings
this way yet; without the two files every other command is unchanged.
Files changed:
- .gitea/workflows/ci.yml
- .gitignore
- AGENTS.md
- CHANGES.md
- INSTALL.md
- VERSION
- docs/explanation/README.md
- docs/explanation/configuration-tiers.md
- docs/how-to/README.md
- docs/how-to/use-1password-for-settings.md
- docs/reference/commands/README.md
- docs/reference/commands/configuration.md
- docs/reference/commands/instance-health.md
- docs/reference/commands/types-instructions-and-docs.md
- docs/reference/configuration.md
- docs/reference/exit-codes.md
- instructions/dev/doc-pull-through.md
- instructions/dev/testing-conventions.md
- instructions/preflight.md
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/cli.py
- tools/chemenu/cli_contract.py
- tools/chemenu/commands/_util.py
- tools/chemenu/commands/config_cmd.py
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/config.py
- tools/chemenu/config_shapes.py
- tools/chemenu/prerequisites.py
- tools/chemenu/settings.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/test_dist_cmd.py
- tools/chemenu/tests/test_preflight.py
- tools/chemenu/tests/test_preflight_pwsh.py
- tools/chemenu/tests/test_settings.py
- tools/chemenu/toolpaths.py
- tools/preflight.ps1
- tools/preflight.sh
- tools/prerequisites.txt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
159 lines
9.2 KiB
Markdown
159 lines
9.2 KiB
Markdown
---
|
|
type: types/instruction.md
|
|
name: preflight
|
|
description: Run the preflight before any wikitool command in a new, cloned, moved or updated checkout - it checks Python, git and ripgrep, records their paths in .wikitool-tools.json and sets up tools/.venv; on exit 42 show its output verbatim and wait for the user, never install or work around anything yourself.
|
|
---
|
|
# Check the machine before anything else runs
|
|
|
|
`tools/wikitool` does not start in a checkout the preflight has not passed in. It stops with
|
|
exit 42 and names this procedure instead - so there is no skipping it, only running it early
|
|
or being sent back to it.
|
|
|
|
The preflight is a script, not a `wikitool` command, because it has to work before Python is
|
|
known to exist: `tools/preflight.sh` for POSIX shells, `tools/preflight.ps1` for PowerShell 7 on
|
|
Windows. The two answer the same questions from the same list and write the same
|
|
`.wikitool-tools.json`. It does three things, all inside the install folder:
|
|
|
|
- checks the tools listed in `tools/prerequisites.txt` - Python 3.11 or newer, git, ripgrep
|
|
(`rg`) - and, on Windows, that the install folder is short enough for Windows' path limit and
|
|
(PowerShell only) that the execution policy and the files' Mark of the Web let
|
|
`tools/wikitool.ps1` start;
|
|
- records the absolute path of each tool in `.wikitool-tools.json`, which `wikitool` then starts
|
|
them from instead of trusting whatever `PATH` a session inherited - and of an optional tool,
|
|
such as the 1Password CLI `op`, when it finds one: an optional tool missing is reported as
|
|
`ABSENT` and is never a reason to stop, nor to install anything;
|
|
- creates `tools/.venv` from the recorded Python and installs `tools/requirements.txt` into it.
|
|
|
|
<!-- wikitool:toc -->
|
|
## Contents
|
|
|
|
- [When to run](#when-to-run)
|
|
- [Steps](#steps)
|
|
- [Decision points](#decision-points)
|
|
- [Scope](#scope)
|
|
<!-- /wikitool:toc -->
|
|
|
|
## When to run
|
|
|
|
- First step of every installation procedure: [setup-instance.md](setup-instance.md) and
|
|
[bootstrap.md](bootstrap.md) both start here.
|
|
- After every stack update ([upgrade-instance.md](upgrade-instance.md)) - a release can change
|
|
what the machine needs, or the requirements the venv holds.
|
|
- Whenever `tools/wikitool` exits 42 and names the preflight, and whenever `tools/wikitool doctor`
|
|
reports `tool-paths`, `install-dir`, `execution-policy` or `script-marks` as `FAIL`.
|
|
|
|
It is safe to run at any time: a second run on a ready checkout changes nothing and exits 0.
|
|
|
|
## Steps
|
|
|
|
1. **Run it** from the root of the checkout, with the script for the shell the session runs in:
|
|
|
|
```bash
|
|
tools/preflight.sh
|
|
```
|
|
|
|
This covers Linux, macOS and Git Bash on Windows, which is where Claude Code runs its
|
|
commands there. From PowerShell 7 on Windows (GitHub Copilot CLI, for one) use the twin, and
|
|
always with exactly this prefix:
|
|
|
|
```powershell
|
|
pwsh -NoProfile -ExecutionPolicy Bypass -File tools/preflight.ps1
|
|
```
|
|
|
|
The bypass holds for that one process only and changes no setting; it is what lets the script
|
|
run at all when the checkout carries a Mark of the Web, so that it can report that itself.
|
|
Windows PowerShell 5.1 is not supported.
|
|
|
|
2. **Read the exit code.**
|
|
|
|
| Exit | Meaning | What you do |
|
|
|---|---|---|
|
|
| 0 | Everything is in place | Continue with the procedure that sent you here |
|
|
| 42 | The user has to act | Step 3 |
|
|
| 1 | Called wrongly, a download or unpack failed (asset mode), or the stack tree next to the script is incomplete | Report the exact command and output to the user; do not retry blindly |
|
|
|
|
3. **On exit 42, show the output to the user exactly as it is, then stop and wait.** It is
|
|
written for someone without an IT background: each numbered block says what is missing, why
|
|
it matters, the command that fixes it, and what happens next. When the user's language is not
|
|
the language of the output, add a translation below it - never instead of it, since the
|
|
commands inside have to reach them unchanged.
|
|
|
|
While you wait, **install nothing, and work around nothing** - not with the user's consent
|
|
either. No package manager call, no other Python, no WSL, no hand-written
|
|
`.wikitool-tools.json`, no `wikitool` command "to see whether it works anyway". The command in
|
|
the output is for the user to run; how their machine is administered is theirs to decide.
|
|
|
|
4. **When the user says it is done, run the preflight again.** Repeat steps 2-4 until it exits 0.
|
|
|
|
When the user tells you where a tool is installed instead, pass the path on:
|
|
|
|
```bash
|
|
tools/preflight.sh --set rg=/opt/ripgrep/rg
|
|
```
|
|
|
|
```powershell
|
|
pwsh -NoProfile -ExecutionPolicy Bypass -File tools/preflight.ps1 --set rg=C:\Tools\rg\rg.exe
|
|
```
|
|
|
|
`--set <tool>=<path>` may be given several times. A path that does not work is refused with
|
|
exit 42 and nothing is written; a working one is recorded and kept on later runs, even though
|
|
the tool is still not on `PATH`.
|
|
|
|
## Decision points
|
|
|
|
- **The script is a release asset, not a tree script** - there is no `tools/prerequisites.txt`
|
|
beside it, because it was downloaded from a release into the empty folder the wiki is to live
|
|
in ([setup-instance.md](setup-instance.md) step 0). That is the *first* install, and the
|
|
script does one more thing before the steps above: it downloads the release tarball and its
|
|
`.sha256`, refuses unless the checksum matches, unpacks the stack into its own folder and
|
|
removes itself there; then it runs the preflight of the installed tree, passing `--set` and
|
|
its exit code through. Run it exactly as in step 1 (the path is the downloaded file, not
|
|
`tools/...`), and read the exit code the same way. After it, every later run - including the
|
|
retry after an exit 42 - is the tree's own `tools/preflight.sh` or `tools/preflight.ps1`.
|
|
- The folder has to be empty apart from the script and a `.git` (an empty clone of the
|
|
instance's own repository). Anything else is refused with exit 1 and nothing is touched -
|
|
which folder to use is the user's decision, not yours to resolve by deleting.
|
|
- `--into <path>` installs into another folder, under the same rule; the script then stays
|
|
where it is.
|
|
- `--archive <tarball>` uses a tarball already on disk, with its `<tarball>.sha256` beside it,
|
|
when the machine cannot download.
|
|
- A checksum that does not match, a failed download, and a copy of the script that carries no
|
|
download address (it was not taken from a release) exit 1 with nothing unpacked; report the
|
|
message, and do not fetch the tarball by another route.
|
|
- A part of the stack that will not move from the unpack folder into place - on Windows a
|
|
virus scanner can hold a freshly unpacked file open for a moment - is retried for about 30
|
|
seconds. If it still fails, the script takes back everything it moved and exits 1 with
|
|
"nothing was installed" and the system's message. Report that message; the folder is as it
|
|
was, and the user may run the script again. If the message instead names entries it could
|
|
not take back, the folder is no longer empty: whether to empty it (keeping `.git`) is the
|
|
user's decision, as above - do not delete anything yourself.
|
|
- On POSIX, `curl`, `tar` and `sha256sum` (or `shasum`) have to exist; when one does not, the
|
|
script stops with exit 42 like any other missing tool. The PowerShell script needs nothing
|
|
beyond what Windows ships.
|
|
- **The output names a folder that is too long.** Only on Windows with long paths off: the
|
|
install folder may be at most 95 characters, because every file of the wiki below it has to
|
|
stay within 259. Moving the wiki to a shorter folder is the user's step; do not try to shorten
|
|
paths inside the wiki instead. In asset mode the length is judged at the folder the stack
|
|
*would* be unpacked into, before anything is unpacked; the fix is a shorter folder (the
|
|
script downloaded there again, or a shorter `--into`).
|
|
- **The output names the PowerShell execution policy** (`Restricted` or `AllSigned`). The fix is a
|
|
line the user runs in a PowerShell 7 window; it changes a setting of their account, so it is
|
|
theirs to run. When a *group policy* sets it, nothing on this computer can override it: the
|
|
output says to ask whoever administers the machine - or to use `tools/wikitool` from Git Bash
|
|
instead. Do not suggest a workaround that evades the policy.
|
|
- **The output names scripts with a Mark of the Web.** The checkout was downloaded with a browser
|
|
and unpacked in Explorer, so Windows marks every file as coming from the internet. The command
|
|
in the output (`Unblock-File` over the folder) is the user's to run; a download by
|
|
`Invoke-WebRequest`, `git clone` or `tar` carries no mark.
|
|
- **The venv or its libraries could not be installed.** The output carries the last lines of
|
|
what Python or pip said. A network, proxy or security-product cause is for the user - or
|
|
whoever administers their machine - to resolve; do not retry with other flags.
|
|
- **`.wikitool-tools.json` looks wrong.** Never edit it. Run the preflight again, with `--set` for
|
|
a path the user names; `doctor` reports whether the result holds.
|
|
|
|
## Scope
|
|
|
|
Not a wiki content procedure - it touches nothing under `kb/`, `raw/`, `work/` or `reports/`.
|
|
It does not configure identity, remotes or the harness either; those are later steps of
|
|
[setup-instance.md](setup-instance.md).
|