docs+install: fix copy-paste-broken commands, count drift & the PATH cliff (18 verified gaps)#74
Conversation
A documentation-completeness audit (agent sweep + direct source checks) found the docs in good shape overall, with a few narrow gaps that hurt "a novice trying to use the project" and "manual completeness". Fixes: - CONFIGS_AUTO.md read "Total configs: 0". The generator globbed builtin/*.yaml non-recursively, but the V2 reorg moved every config into tier subdirs (model/ presets/ profile/ hardware/). Rewrote discovery to recurse the four tiers (excluding retired _archive/), tag each config's tier, and render a per-tier inventory (model tier keeps the rich engine table; presets show their model×hardware×profile triplet). Now reports the real 45 active configs. TDD: added TestLiveInventoryNonEmpty (non-empty, tier discovery, count-matches-disk) — red on the old glob, green after. render_markdown split into helpers (drops the PLR0915 over-limit); ruff-clean. - docs/CONFIGS.md: dropped the stale "CONFIGS_AUTO.md remains a placeholder stub pending a V2 inventory generator" note — the generator now exists. - CLI_REFERENCE.md: added reference entries (flags + examples) for `sndr quickstart` (the flagship zero-decision front door every onboarding doc points at, previously undocumented) and `sndr remote setup` (client mode: --key/--dsn/--write-env). Flags verified against the live --help. - GUI.md: documented Simple vs Expert mode — a fresh user lands in the 5-section Simple surface (Overview / Choose & Launch / Chat & Copilot / Doctor / Advanced) with a topbar Simple<->Expert toggle; the ~24-section Screens table is the Expert catalog. Previously the manual only described the Expert workbench, never the surface a novice actually sees. - docs/README.md: file-catalogue count 49 -> 50 (stale by one). - sndr/cli/__main__.py: docstring only. An investigation into why `python -m sndr.cli quickstart` errors while `sndr quickstart` works showed the two entry points are DELIBERATELY different surfaces — the `sndr` binary is the curated first-run dispatcher; `python -m sndr.cli` is the full legacy/infra surface (gui-api, k8s, routing-table, …) that the Makefile gui-api target, the compose daemon and the smoke scripts depend on. Rewrote the misleading "both reach the same dispatcher" docstring to state the split accurately, so the next reader doesn't "unify" them and break daemon launch (as an initial attempt here did — caught by the existing tests/unit/cli/test_gui_api_cli.py).
…etup examples The sndr remote setup examples in CLI_REFERENCE.md used the actual server LAN IP 192.168.1.10, which trips the audit_public_docs D-2 (no private IPs) and security_scan (private_ips) gates. Switch to the repo's <rig> placeholder convention (matches RUN_ON_MAC.md / REMOTE_ENGINE.md).
…TH cliff A 34-agent adversarial verification of documentation completeness confirmed 18 real gaps (8 candidates dismissed as false positives). This closes them. BLOCKER — commands that hard-fail on copy-paste (verified via live --help): - CLI_REFERENCE: `patches prove --filter PN95` -> positional `patches prove PN95`; `release-check --mode require-bench-attached` -> `--mode require-bench`; `bench-attach PN119 --bench x --pin y` -> positional `bench-attach PN119 x`. - USAGE: `launch <preset> --preflight-only` -> the dedicated `sndr preflight <preset>` verb; `patches plan <preset>` -> `patches plan --preset <preset>`. Novice onboarding cliffs: - install.sh: the `sndr` console script installs to the Python user-scripts dir (~/.local/bin) which is often off PATH, so a newcomer's first `sndr` command died with "command not found". print_next_steps now detects this and prints the exact fix (export PATH / `python -m sndr.cli`). TDD: test_next_steps_has_path_guard (red -> green); bash -n clean. - RUN_ON_LINUX: added the Docker + nvidia-container-toolkit + driver >=580.126.09 prerequisite to the zero-decision front door (was only in INSTALL.md). - INSTALL: added the `--client`/`--no-engine` flag to the installer flag matrix (anchors the whole Mac/Windows client-mode story; was undocumented there). - RUN_ON_MAC: the `.env` alternative said `cp .env.example .env`, but after a `--client` install .env.example is not in CWD (repo lives at ~/.sndr) and the installer already wrote a client .env — corrected to "edit the .env the installer wrote". Count / content drift (with a new regression gate so it can't recur): - README "58 of 329" and FAQ "56 of 325" default_on -> both 56 of 329 (live registry). New gate tests/unit/docs/test_default_on_count_consistency.py validates every curated doc's default_on count against PATCH_REGISTRY (proven to catch a reintroduced 58). - USAGE "12 builtin configs auto-inventoried in CONFIGS_AUTO.md" -> "45 active (12 model / 15 presets / 15 profile / 3 hardware)" after the tier-recursion. - CONFIGURATION/PATCHES: P56/P57 env flags marked REMOVED (archived 2026-05-05, absent from PATCH_REGISTRY — setting them was inert). - GUI: dropped the false "complete Expert catalog" claim (the table omits the Memory and Hardware sections) and added them to the workbench list. MINOR: - CLI_REFERENCE: `--ctx-scale` documented as a comma LIST but the flag takes a single ceiling label (1K..512K); `tune revert`/`tune sweep` examples restored their required `config`/`--low`/`--high` args; documented `chat --api-key`.
There was a problem hiding this comment.
Code Review
This pull request updates the documentation, CLI references, and configuration generation scripts to support the V2 layered configuration structure, which organizes configurations into tier subdirectories (model, presets, profile, hardware). It also introduces a quickstart command, a client-only installation option, a PATH guard warning in install.sh, and consistency tests for default-on patch counts. The review feedback suggests specifying encoding="utf-8" when reading files in tests to prevent cross-platform failures on Windows, setting check=True on subprocess calls in tests to fail fast with clear errors, and verifying the existence of the user's Python user-base bin directory in install.sh before suggesting it in the PATH warning.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| for doc in CURATED_DOCS: | ||
| if not doc.is_file(): | ||
| continue | ||
| text = doc.read_text() |
There was a problem hiding this comment.
Reading files without specifying an encoding can lead to UnicodeDecodeError on platforms where the default encoding is not UTF-8 (such as Windows), especially since these markdown files contain non-ASCII characters like ⇄ and ≥. Specifying encoding="utf-8" ensures cross-platform compatibility.
| text = doc.read_text() | |
| text = doc.read_text(encoding="utf-8") |
| user-scripts dir (~/.local/bin / ~/Library/Python/X.Y/bin), often off PATH. | ||
| print_next_steps MUST detect that and print a remediation, or a beginner's | ||
| first `sndr` command dies with 'command not found'.""" | ||
| content = INSTALL_SH.read_text() |
There was a problem hiding this comment.
Reading install.sh without specifying an encoding can cause UnicodeDecodeError on Windows systems because the file contains non-ASCII characters like ⚠ and ✓. Specifying encoding="utf-8" prevents cross-platform test failures.
| content = INSTALL_SH.read_text() | |
| content = INSTALL_SH.read_text(encoding="utf-8") |
| capture_output=True, | ||
| text=True, | ||
| timeout=15, | ||
| check=False, |
There was a problem hiding this comment.
Using check=False without verifying the returncode means that if the subprocess fails, the test will continue with potentially empty stdout and fail with a confusing assertion error (e.g., no Total configs marker in output) rather than showing the actual subprocess error/stderr. Setting check=True will raise a CalledProcessError with the failure details immediately.
| check=False, | |
| check=True, |
| _sndr_user_bin="$("$PYTHON_BIN" -c 'import site; print(site.getuserbase())' 2>/dev/null)/bin" | ||
| printf '%b\n' "${C_YELLOW}${C_BOLD}⚠ \`sndr\` is not on your PATH yet${C_RESET} — add its bin dir or use the module form:" | ||
| echo " export PATH=\"${_sndr_user_bin}:\$PATH\" # this shell (add to ~/.bashrc or ~/.zshrc to persist)" | ||
| echo " $PYTHON_BIN -m sndr.cli <command> # always works, no PATH change" |
There was a problem hiding this comment.
If site.getuserbase() fails or returns an empty string, _sndr_user_bin will resolve to /bin. Printing export PATH="/bin:\$PATH" is confusing to users since /bin is already on the system PATH. It is safer to verify that the user base directory and its bin subdirectory actually exist before suggesting the export PATH command, falling back gracefully to only showing the module form.
| _sndr_user_bin="$("$PYTHON_BIN" -c 'import site; print(site.getuserbase())' 2>/dev/null)/bin" | |
| printf '%b\n' "${C_YELLOW}${C_BOLD}⚠ \`sndr\` is not on your PATH yet${C_RESET} — add its bin dir or use the module form:" | |
| echo " export PATH=\"${_sndr_user_bin}:\$PATH\" # this shell (add to ~/.bashrc or ~/.zshrc to persist)" | |
| echo " $PYTHON_BIN -m sndr.cli <command> # always works, no PATH change" | |
| _sndr_user_base="$("$PYTHON_BIN" -c 'import site; print(site.getuserbase())' 2>/dev/null)" | |
| printf '%b\n' "${C_YELLOW}${C_BOLD}⚠ \`sndr\` is not on your PATH yet${C_RESET} — add its bin dir or use the module form:" | |
| if [ -n "$_sndr_user_base" ] && [ -d "$_sndr_user_base/bin" ]; then | |
| echo " export PATH=\"$_sndr_user_base/bin:\$PATH\" # this shell (add to ~/.bashrc or ~/.zshrc to persist)" | |
| fi | |
| echo " $PYTHON_BIN -m sndr.cli <command> # always works, no PATH change" |
ruff-changed lints the whole of any changed file, so appending to the pre-existing-baseline-dirty test_installer.py surfaced its 6 grandfathered findings and failed CI. Restore test_installer.py to its committed state and put the PATH-guard assertions in a new, fully ruff-clean file instead.
Why
A 34-agent adversarial verification of documentation completeness (8 dimensions, each finding then independently skepticism-checked) confirmed 18 real gaps and correctly dismissed 8 false positives (e.g. Docker/nvidia-toolkit IS covered in
preflight_check.sh; the bare-metalvllm==0.20.1is the deliberate Proxmox workaround). This PR closes the 18.BLOCKER — commands that hard-fail on copy-paste (each verified against live
--help)patches prove --filter PN95patches prove PN95(positional)release-check --mode require-bench-attached--mode require-benchbench-attach PN119 --bench x --pin ybench-attach PN119 x(positional)launch <preset> --preflight-onlysndr preflight <preset>patches plan <preset>patches plan --preset <preset>Novice onboarding cliffs
sndrscript installs to~/.local/bin, often off PATH → the firstsndrcommand died with "command not found".print_next_stepsnow detects it and prints the fix (export PATH /python -m sndr.cli). TDDtest_next_steps_has_path_guard(red→green),bash -nclean.--client/--no-engineto the installer flag matrix (anchors the Mac/Windows client story)..envalternative (cp .env.example .envfails after a--clientinstall — the file isn't in CWD; the installer already wrote one).Count / content drift — with a regression gate
test_default_on_count_consistency.pyvalidates every curated doc's default_on count againstPATCH_REGISTRY(proven to catch a reintroduced 58).MINOR
--ctx-scalelist→single-ceiling;tune revert/sweeprequired args restored; documentedchat --api-key.Verification
.py;bash -n install.shclean--checkgenerators ✓