lacs-project / lacs-project/sysknife
docs/cli.md and the binary disagree on the unattended flag, and omit the variable that controls audit commands
- Dominant language
- Rust
- Stars
- 12
- Forks
- 19
- Avg merge
- 18h 57m
- Merged PRs (30d)
- 116
Description
Four gaps between `docs/cli.md` and what an operator actually gets, found by building a real nightly job from the docs alone.
## 1. `--help` and `docs/cli.md` state different contracts for `--dangerously-skip-approval`
`--help` says:
> Implies `--yes`, `--max-risk high` and `--non-interactive` unless you set a lower `--max-risk`, which still wins.
`docs/cli.md` says:
> `--yes` may now auto-approve HIGH-risk steps. The cap moves from MEDIUM to HIGH.
The second reads as though `--yes` still has to be typed, and never mentions `--non-interactive` at all. That difference changes what a script must pass, and it changes what `--step-by-step` combined with the flag does. Whichever is right, the other has to move.
## 2. The flag gates and banners subcommands that approve nothing
```
$ SYSKNIFE_I_ACCEPT_UNATTENDED_ROOT=1 sysknife audit export --dangerously-skip-approval
[]
(full UNATTENDED MODE banner on stderr)
$ sysknife doctor --dangerously-skip-approval # env var unset
sysknife: --dangerously-skip-approval was passed but SYSKNIFE_I_ACCEPT_UNATTENDED_ROOT is not set to 1.
$ echo $?
1
```
This is deliberate, and the reason is in the source: a flag that is sometimes silently ignored teaches people it is harmless. But `docs/cli.md` frames the whole section around plan execution, and the only hint is one line under Global flags saying all flags apply to every subcommand.
A wrapper that uniformly appends the flag to every invocation, which is a normal "always non-interactive" pattern, gets hard refusals on health checks and audit shipping. Say so in the Unattended mode section.
Stream separation is correct here: the banner is on stderr and stdout stays clean, so `jq` still parses. Only the scope is undocumented.
## 3. `SYSKNIFE_DATABASE_PATH` is missing, and `SYSKNIFE_SOCKET` does nothing for audit commands
```
$ grep -c SYSKNIFE_DATABASE_PATH docs/cli.md
0
```
`developer-guide.md` and `the-audit-chain.md` both document it as the way to point `audit export` and `audit verify` at a specific store, including a copied remote database. `docs/cli.md`'s own Environment variables section never mentions it.
Worse, the reverse is implied. `SYSKNIFE_SOCKET` has its own entry warning about forwarded sockets, and `audit verify --pubkey` is described as the auditor path, so pointing `SYSKNIFE_SOCKET` at a particular daemon looks like it selects which trail you export. It does not. Audit commands never dial the daemon; they read a local file. In a fleet with several daemons that is a silent wrong answer.
## 4. `--log-to` is a stdout-only tee, and the doc's own example produces an empty file on failure
Running `docs/cli.md`'s own Scripting and CI example verbatim, on a run that failed:
```
$ cat /tmp/.../nightly.log
# 0 bytes
```
Every diagnostic line goes to stderr: the provider fallback notice, the planning status, and the final error. `--log-to` tees stdout only. On the one occasion an operator needs the log, it is empty, and nothing in the section says to capture stderr separately.
## Scope
All four are `docs/cli.md`, except #1 which needs someone to decide which of the two statements is true and correct the other.
## Difficulty
`easy`. Four sections of one file, plus reading `main.rs` once to settle #1.
## Getting started
[CONTRIBUTING.md](https://github.com/lacs-project/sysknife/blob/main/CONTRIBUTING.md) has the build and test commands. `docs/cli.md` is not in the CI markdownlint list, so check it with `npx markdownlint-cli2 docs/cli.md` before pushing. No CLA and no copyright waiver. The project is MIT.
Contributor guide
Research direction
Read docs/cli.md alongside the --help output and the relevant logic in main.rs, first settling which unattended-flag contract is authoritative. Update the four documented gaps, including audit database selection and stderr logging, then run npx markdownlint-cli2 docs/cli.md and verify the examples and environment-variable descriptions match the observed behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, documentation
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- Half a day
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 78/100