Skip to content

Config audit, self-uninstall, stage dry runs and wider e2e coverage (3.5.0-F19, B139-B143, DEV23, DOC15) - #8

Merged
KeithRaghubar merged 11 commits into
mainfrom
fix/config-audit
Oct 24, 2026
Merged

KeithRaghubar merged 11 commits into
mainfrom
fix/config-audit

Conversation

@KeithRaghubar

Copy link
Copy Markdown
Owner

Summary

  • DOC15: audit of the shipped etc/sysforge/*.toml comments against the code (the optimized profile's linker note, kernel.toml's scripts/config and "no kernel PGO" claims, nonexistent bootstrap stage names, a per-user sysforge.toml that is never read, DESIGN.md pointers the package does not install). DOC scope now covers shipped config comments.
  • B139: a packages.toml cache = false entry now turns ccache and sccache off for that package (CCACHE_DISABLE=1, empty RUSTC_WRAPPER); the "required for PGO" claim is gone.
  • B140: [failure_handling] is read from sysforge.toml (it was read from profiles.toml). failure.SCENARIOS holds each key's own values and default; checksum_mismatch accepts only prompt_user or abort.
  • B141: run kernel/toolchain/packages --dry-run runs the stage and shows its plan (the kernel's "Kernel build plan") instead of one hidden INFO line. Dry-run state is read-only, no sentinels, and the toolchain stage never clones a missing PKGBUILD.
  • B142: the artifact registry resolves its state dir through resolve_state_dir, so a first-session artifact write no longer crashes.
  • B143: sysforge uninstall --yes; without it and without a terminal it refuses before pacman runs.
  • F19: sysforge self-uninstall reverts every source build a repo carries, keeps the rest, removes sf-build from IgnoreGroup and the chroot's local repo, then removes the package, its data and the group. --dry-run, --yes, --keep-data. Revert planning/execution and the IgnoreGroup helpers now live once in verbs/shared.py.
  • DEV23: eight new e2e scenarios (36 of 43 commands run; the rest excused with a reason in tools/e2e/uncovered.toml), make e2e-coverage, and tests/test_e2e_coverage.py failing on a command neither run nor excused.

e2e stays a non-required check on main.

Test plan

  • make test: 7615 passed
  • make e2e (podman, a container per scenario): all 12 pass
  • make e2e E2E_HERE=1 in a fresh archlinux:base-devel container (CI's shared-system mode): all 12 pass
  • make lint, check-design, check-standards, check-shipped, check-surface, check-roadmap-table

🤖 Generated with Claude Code

KeithRaghubar and others added 11 commits October 24, 2026 10:59
Audit of etc/sysforge/*.toml for statements the code contradicts: the
optimized profile's linker note, kernel.toml's scripts/config and "no
kernel PGO" claims, bootstrap.toml's nonexistent stage names, a
per-user sysforge.toml that is never read, and DESIGN.md pointers the
package does not install. Internal stage and pass numbering fixed in
the design docs and sysforge/CLAUDE.md. DOC scope now covers shipped
config comments. Files 3.5.0-B139, B140 and DEV23.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
packages add --no-cache recorded cache = false but no build read it.
makepkg_wrapper.run now looks the build up in packages.toml
(config.cache_disabled_for, entries and group defaults) and adds
CCACHE_DISABLE=1 and an empty RUSTC_WRAPPER to its injected env, which
win over BUILDENV, a ccache PATH directory and a shell-exported
wrapper. Drops the "required for PGO" claim from the help, completion,
man page, shipped config and design doc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
makepkg_wrapper.run passed every reader the profiles.toml dict, so the
documented sysforge.toml section did nothing. failure.SCENARIOS is now
the one home for each key's accepted values and default;
resolve_failure_handling validates the sysforge.toml table and run()
folds it into the config the readers already take. checksum_mismatch
accepts only prompt_user or abort, and an unexpected auto-repair value
aborts instead of repairing. Drops the five scenarios nothing raises
and documents the three live ones in the shipped file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
….0-DEV23)

Six new scenarios (maintain, revert-to-stock, config, inspect,
artifacts, source-policy) and a seventh, xfail, previewing run
toolchain/kernel with non-default configs. tools/e2e_coverage.py
compares surface.json's commands with the scenarios;
tests/test_e2e_coverage.py fails on a command that is neither run nor
excused with a reason in tools/e2e/uncovered.toml. make e2e-coverage
prints both sets. lib.sh gains expect_exit_in, json_report, output_has
(both streams, no pipe under pipefail) and assert_not_installed.

Files two bugs the scenarios found: 3.5.0-B141 (stage --dry-run skips
the stage and prints nothing) and 3.5.0-B142 (artifact registry
bypasses resolve_state_dir, so it crashes in a first session).
Passes in podman and in CI's shared-system mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (3.5.0-B142)

ArtifactRegistry and IgnoreList resolved /var/lib/sysforge themselves,
so they never provisioned it: a first-session artifact write crashed
with PermissionError. Reads now resolve with provision=False and the
first save provisions, as a build's run does. build_sandbox's
source-built lookup uses the same read-only resolution; stage_sentinel
and init_notice keep the fixed default deliberately (lock and marker
live there). 85-artifacts drops its provisioning build and becomes the
regression scenario.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
uninstall left the confirmation to pacman -Rnsu with no --yes, so a
scripted run read EOF at [Y/n] and failed with a raw command line.
--yes passes --noconfirm; without it and without a terminal the verb
refuses before pacman runs, as revert-to-stock does. Completions, man
page and surface updated; 50-maintain checks the refusal and the
interactive path. Tests that built uninstall args as SimpleNamespace
now use cli_args.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
run_stage_standalone returned before stage.run on --dry-run, logging
one INFO line, so `run kernel --dry-run` printed nothing and never
reached the dry-run handling every stage already carries. It now runs
the stage after a ui() `[dry-run] <stage>` line. PipelineState gains
read_only, set for every dry run, so a stage's mid-run checkpoints
never reach the file; the kernel install window and the packages loop
take no sentinel on a dry run. run pipeline --dry-run keeps its stage
list (the bootstrap stages are not dry-run safe). 95-stage-dry-run
drops its xfail and checks the records, not the state-dir listing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (3.5.0-F19)

Plans by reading only: every source build goes through plan_revert,
reverted when the sync DB (new pacman.get_sync_pkgnames, one -Slq)
carries its stock names, kept installed otherwise. Then drops sf-build
from IgnoreGroup (setup_cmd._unpatch_conf_text, the inverse of
_patch_conf_text) and the chroot's local repo block, and removes the
package, paths.PACKAGE_DIRS and the group in one sudo sh -c, last,
since the process may import nothing after pacman deletes it.
Reverts run through revert_cmd.apply_reverts, now extracted as the one
home both verbs call, under the verb's own sentinel. --dry-run, --yes,
--keep-data. The guide's manual removal list (and its wrong .pacsave
claim) is replaced; 99-self-uninstall runs it on a live system.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the stage now running under --dry-run, resolve_all_pkgbuilds
cloned the llvm and spirv-llvm-translator packaging repos when they
were missing (and needed pkgctl to do it), found by the shared-system
e2e run after 40-pre-install-failure removes devtools. dry_run=True
reads only checked-out PKGBUILDs and raises CheckoutsMissing; the stage
names what it would clone and ends the preview. No sync or purge either.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
….0-F19)

self_uninstall_cmd imported from revert_cmd and setup_cmd, which
test_verb_modules_do_not_import_siblings forbids: verb modules are
peers. plan_revert (with its helpers) and apply_reverts move to
verbs/shared.py, re-exported by revert_cmd; the IgnoreGroup name,
regex, check and removal (drop_ignore_group, remove_ignore_group) move
there too, and setup_cmd keeps its add path. Tests patch
forget_packages and the revert logger where the code now lives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@KeithRaghubar
KeithRaghubar merged commit f2f523a into main Oct 24, 2026
2 checks passed
@KeithRaghubar
KeithRaghubar deleted the fix/config-audit branch October 24, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant