Kernel Surface Ledger ksl
Every other tool tells you what kernel attack surface is exposed. This one tells you who is responsible for it, what nothing is using, and the shortest way out.
total surface weight
149
every element present, reachable or not
reachable surface weight
106after plan 43.5
reachable by an unprivileged local user
reachable CVEs
19after plan 9
CVE mass behind reachable surface
orphan ratio
49.1%
reachable weight touched by nothing
00 / interrogate
Ask this report
The narration layer, live and grounded: it answers from the loaded JSON, cites element and workload ids, and names what the data cannot tell you rather than guessing.
Grounded in the loaded report only. If the answer is not in the data, it says what is missing instead of inventing it.
01 / attribution
Surface Debt Ledger
Dangerous kernel surface is a jointly held liability across every live workload on the host. Each row is one workload's share: its debt, its marginal contribution, the surface it alone keeps open, and the CVE mass that surface exposes. Expand a row for the causal narration. The last row is the point.
| expand | sole owner | ||||
|---|---|---|---|---|---|
| dockerddocker.service unprivileged user namespacesio_uring_setupkeyctl | 17.25 | 9.50 | 9 | yes · 1 | |
| libvirtdlibvirtd.service /dev/kvm | 7 | 7 | 1 | yes · 1 | |
| nginxnginx.service io_uring_setup | 4.50 | 0 | 3 | no | |
| udisksdudisks2.service usb-storage | 4.50 | 4.50 | 1 | yes · 1 | |
| sshdssh.service keyctl | 3.25 | 0 | 2 | no | |
| orphaned reachable by any local user, touched by nothing — 8 elements | 52 | — | 7 | — |
02 / free hardening
Orphaned surface
Present, reachable by any unprivileged local user, and used by nothing during the observation window. Removing it is provably zero-impact — nothing touches it.
52weighted units of unprivileged-reachable surface
7CVEs neutralizable at zero cost
bluetooth
6mod.bluetooth
gate: loaded: bluetooth
dccp
7mod.dccp
gate: not loaded but autoloadable via modules.dep (dccp)
cramfs / freevxfs / jffs2 / hfsplus / udf
5mod.legacy_fs
gate: not loaded but autoloadable via modules.dep (cramfs, freevxfs, hfsplus, jffs2, udf)
n_hdlc
5.5mod.n_hdlc
gate: not loaded but autoloadable via modules.dep (n_hdlc)
rds
6.5mod.rds
gate: not loaded but autoloadable via modules.dep (rds)
tipc
6.5mod.tipc
gate: not loaded but autoloadable via modules.dep (tipc)
perf_event_open
7.5sc.perf_event_open
gate: kernel.perf_event_paranoid=2
userfaultfd
8sc.userfaultfd
gate: vm.unprivileged_userfaultfd=1
03 / reachability, not mere presence
Three-tier gates
A CVE in a module that cannot be loaded is irrelevant; one reachable by any local user is critical. Every element passes present → reachable_unpriv → used, and module autoload turns 'not loaded' into one socket() call away.
| element | weight | present | reachable unpriv | used | gate reason / mitigations |
|---|---|---|---|---|---|
CAP_SYS_ADMIN held by non-root workload cap.sys_admin_unpriv capabilitycapabilitiesnot presentcap-sys-admin-abuse | 9 | present: no | reachable by unprivileged user: no | used by a live workload: no | no non-root workload holds CAP_SYS_ADMIN
|
kernel.dmesg_restrict = 0 cfg.dmesg_open sysctlinfoleakreachable · usedinfoleak | 4 | present: yes | reachable by unprivileged user: yes | used by a live workload: yes | kernel.dmesg_restrict=0
|
CONFIG_COMPAT (32-bit emulation) cfg.kconfig_compat kconfigcompatreachable · unusedcompat-ioctls | 5.5 | present: yes | reachable by unprivileged user: yes | used by a live workload: no | compiled in |
unrestricted module autoload cfg.module_autoload sysctlmodulesreachable · usedautoload-amplifier | 7.5 | present: yes | reachable by unprivileged user: yes | used by a live workload: yes | kernel.modules_disabled=0
|
kernel.kptr_restrict < 2 cfg.no_kptr_restrict sysctlinfoleakreachable · usedinfoleak | 5 | present: yes | reachable by unprivileged user: yes | used by a live workload: yes | kernel.kptr_restrict=1
|
lockdown LSM inactive cfg.no_lockdown lsmlsmpresent · gatedkernel-integrity | 6 | present: yes | reachable by unprivileged user: no | used by a live workload: no | root-only impact
|
/dev/kvm dev.kvm devnodekvmreachable · usedkvm-ioctl | 7 | present: yes | reachable by unprivileged user: yes | used by a live workload: yes | mode 0666 grants non-root
|
/dev/mem dev.mem devnodemmpresent · gatedphysical-memory-access | 9 | present: yes | reachable by unprivileged user: no | used by a live workload: no | blocked: mode 0640 denies non-root
|
bluetooth mod.bluetooth modulebluetoothreachable · unusedbluetooth-parsing | 6 | present: yes | reachable by unprivileged user: yes | used by a live workload: no | loaded: bluetooth
|
dccp mod.dccp modulenetreachable · unuseddccp-uafnet-legacy-proto | 7 | present: yes | reachable by unprivileged user: yes | used by a live workload: no | not loaded but autoloadable via modules.dep (dccp)
|
firewire-core mod.firewire_core modulefirewirenot presentdma-physical-access | 6 | present: no | reachable by unprivileged user: no | used by a live workload: no | not present on host
|
cramfs / freevxfs / jffs2 / hfsplus / udf mod.legacy_fs modulefsreachable · unusedfs-image-parsing | 5 | present: yes | reachable by unprivileged user: yes | used by a live workload: no | not loaded but autoloadable via modules.dep (cramfs, freevxfs, hfsplus, jffs2, udf)
|
n_hdlc mod.n_hdlc modulettyreachable · unusedtty-ldisc-lpe | 5.5 | present: yes | reachable by unprivileged user: yes | used by a live workload: no | not loaded but autoloadable via modules.dep (n_hdlc)
|
rds mod.rds modulenetreachable · unusednet-legacy-proto | 6.5 | present: yes | reachable by unprivileged user: yes | used by a live workload: no | not loaded but autoloadable via modules.dep (rds)
|
tipc mod.tipc modulenetreachable · unusednet-legacy-protoremote-heap-overflow | 6.5 | present: yes | reachable by unprivileged user: yes | used by a live workload: no | not loaded but autoloadable via modules.dep (tipc)
|
usb-storage mod.usb_storage moduleusbnot presentusb-parsing | 4.5 | present: no | reachable by unprivileged user: no | used by a live workload: yes | not present on host
|
unprivileged user namespaces ns.userns_unpriv namespacenamespacesreachable · usednetfilter-via-usernsuserns-lpe | 9.5 | present: yes | reachable by unprivileged user: yes | used by a live workload: yes | kernel.unprivileged_userns_clone=1
|
bpf (unprivileged) sc.bpf_unpriv syscallbpfpresent · gatedbpf-verifier | 8.5 | present: yes | reachable by unprivileged user: no | used by a live workload: no | blocked: kernel.unprivileged_bpf_disabled=1
|
io_uring_setup sc.io_uring_setup syscallio_uringreachable · usedio_uring-refcountio_uring-uaf | 9 | present: yes | reachable by unprivileged user: yes | used by a live workload: yes | kernel.io_uring_disabled=0
|
keyctl sc.keyctl syscallkeysreachable · usedkeyring-uafrefcount-overflow | 6.5 | present: yes | reachable by unprivileged user: yes | used by a live workload: yes |
|
perf_event_open sc.perf_event_open syscallperfreachable · unusedinfoleakperf-lpe | 7.5 | present: yes | reachable by unprivileged user: yes | used by a live workload: no | kernel.perf_event_paranoid=2
|
userfaultfd sc.userfaultfd syscallmmreachable · unusedheap-grooming-primitive | 8 | present: yes | reachable by unprivileged user: yes | used by a live workload: no | vm.unprivileged_userfaultfd=1
|
04 / counterfactual
Hardening plan
Hardening as weighted set cover: the changes that neutralize maximum reachable CVE mass per unit of estimated breakage. Not an unranked findings list — an ordered plan, each step shipping an artifact, a breakage prediction, a detection command and a revert.
cumulative CVE mass killed
5
7
12
13
16
5 steps → 16 reachable CVEs neutralized
step 1blacklist_module
bluetoothcramfsdccpfreevxfshfsplusjffs2n_hdlcrdstipcudfbreakage: none5 CVEs killed−36.5 weightwhat could break
If a Bluetooth service (bluetoothd) is started, it would fail to load the bluetooth module
detect it worked
detectionmodprobe bluetooth 2>&1 | grep -i blacklistedrevert
revertsudo sed -i '/^blacklist bluetooth$/d; /^blacklist cramfs$/d; /^blacklist dccp$/d; /^blacklist freevxfs$/d; /^blacklist hfsplus$/d; /^blacklist jffs2$/d; /^blacklist n_hdlc$/d; /^blacklist rds$/d; /^blacklist tipc$/d; /^blacklist udf$/d' /etc/modprobe.d/blacklist.confcheck this — did step 1 work?
1the check shipped with this step
$ modprobe bluetooth 2>&1 | grep -i blacklistedgood: Output matches what the step describes — the change is in effect on this host.
not good: Empty or contradicting output means the change is not active yet. Apply the artifact, then run this again.
2module bluetooth is not loaded
$ lsmod | grep -w bluetooth || echo "not loaded"good: You see "not loaded" — bluetooth is out of the kernel.
not good: Output means bluetooth is still loaded: run "sudo modprobe -r bluetooth" (or reboot if it is in use).
3bluetooth can no longer autoload
$ modprobe -n -v bluetoothgood: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …bluetooth.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
4module cramfs is not loaded
$ lsmod | grep -w cramfs || echo "not loaded"good: You see "not loaded" — cramfs is out of the kernel.
not good: Output means cramfs is still loaded: run "sudo modprobe -r cramfs" (or reboot if it is in use).
5cramfs can no longer autoload
$ modprobe -n -v cramfsgood: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …cramfs.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
6module dccp is not loaded
$ lsmod | grep -w dccp || echo "not loaded"good: You see "not loaded" — dccp is out of the kernel.
not good: Output means dccp is still loaded: run "sudo modprobe -r dccp" (or reboot if it is in use).
7dccp can no longer autoload
$ modprobe -n -v dccpgood: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …dccp.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
8module freevxfs is not loaded
$ lsmod | grep -w freevxfs || echo "not loaded"good: You see "not loaded" — freevxfs is out of the kernel.
not good: Output means freevxfs is still loaded: run "sudo modprobe -r freevxfs" (or reboot if it is in use).
9freevxfs can no longer autoload
$ modprobe -n -v freevxfsgood: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …freevxfs.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
10module hfsplus is not loaded
$ lsmod | grep -w hfsplus || echo "not loaded"good: You see "not loaded" — hfsplus is out of the kernel.
not good: Output means hfsplus is still loaded: run "sudo modprobe -r hfsplus" (or reboot if it is in use).
11hfsplus can no longer autoload
$ modprobe -n -v hfsplusgood: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …hfsplus.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
12module jffs2 is not loaded
$ lsmod | grep -w jffs2 || echo "not loaded"good: You see "not loaded" — jffs2 is out of the kernel.
not good: Output means jffs2 is still loaded: run "sudo modprobe -r jffs2" (or reboot if it is in use).
13jffs2 can no longer autoload
$ modprobe -n -v jffs2good: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …jffs2.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
14module n_hdlc is not loaded
$ lsmod | grep -w n_hdlc || echo "not loaded"good: You see "not loaded" — n_hdlc is out of the kernel.
not good: Output means n_hdlc is still loaded: run "sudo modprobe -r n_hdlc" (or reboot if it is in use).
15n_hdlc can no longer autoload
$ modprobe -n -v n_hdlcgood: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …n_hdlc.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
16module rds is not loaded
$ lsmod | grep -w rds || echo "not loaded"good: You see "not loaded" — rds is out of the kernel.
not good: Output means rds is still loaded: run "sudo modprobe -r rds" (or reboot if it is in use).
17rds can no longer autoload
$ modprobe -n -v rdsgood: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …rds.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
18module tipc is not loaded
$ lsmod | grep -w tipc || echo "not loaded"good: You see "not loaded" — tipc is out of the kernel.
not good: Output means tipc is still loaded: run "sudo modprobe -r tipc" (or reboot if it is in use).
19tipc can no longer autoload
$ modprobe -n -v tipcgood: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …tipc.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
20module udf is not loaded
$ lsmod | grep -w udf || echo "not loaded"good: You see "not loaded" — udf is out of the kernel.
not good: Output means udf is still loaded: run "sudo modprobe -r udf" (or reboot if it is in use).
21udf can no longer autoload
$ modprobe -n -v udfgood: "install /bin/false" (or an error) — nothing can pull it in automatically.
not good: An "insmod …udf.ko" line means the blacklist did not take: check /etc/modprobe.d/ and run "sudo depmod -a".
22nothing important broke
$ systemctl --failed --no-legend; journalctl -p err -b --since "10 min ago" | tail -20good: No failed units and no new kernel/service errors — the change was safe on this host.
not good: A failed unit or a new error right after the change is your signal to revert with: sudo sed -i '/^blacklist bluetooth$/d; /^blacklist cramfs$/d; /^blacklist dccp$/d; /^blacklist freevxfs$/d; /^blacklist hfsplus$/d; /^blacklist jffs2$/d; /^blacklist n_hdlc$/d; /^blacklist rds$/d; /^blacklist tipc$/d; /^blacklist udf$/d' /etc/modprobe.d/blacklist.conf
generated artifact
/etc/modprobe.d/ksl-blacklist.conf# generated by kernel-surface-ledger - revert: kernel-surface-ledger generate blacklist_module blacklist bluetooth install bluetooth /bin/false blacklist cramfs install cramfs /bin/false blacklist dccp install dccp /bin/false blacklist freevxfs install freevxfs /bin/false blacklist hfsplus install hfsplus /bin/false blacklist jffs2 install jffs2 /bin/false blacklist n_hdlc install n_hdlc /bin/false blacklist rds install rds /bin/false blacklist tipc install tipc /bin/false blacklist udf install udf /bin/falsegenerated for review — ksl never applies hardening itself
step 2seccomp_filter
perf_event_openbreakage: none2 CVEs killedwhat could break
perf tool (e.g., perf record) could fail due to blocked perf_event_open
detect it worked
detectiondmesg | grep -i seccomprevert
revertsed -i '/seccomp_filter=perf_event_open/d' /etc/default/grub && update-grubcheck this — did step 2 work?
1the check shipped with this step
$ dmesg | grep -i seccompgood: Output matches what the step describes — the change is in effect on this host.
not good: Empty or contradicting output means the change is not active yet. Apply the artifact, then run this again.
2perf_event_open is gated by kernel.perf_event_paranoid
$ sysctl kernel.perf_event_paranoidgood: The value shown is the restricted one, so an ordinary user can no longer use perf_event_open.
not good: An unrestricted value means perf_event_open is still reachable by any local user. Re-apply the step's artifact.
3nothing important broke
$ systemctl --failed --no-legend; journalctl -p err -b --since "10 min ago" | tail -20good: No failed units and no new kernel/service errors — the change was safe on this host.
not good: A failed unit or a new error right after the change is your signal to revert with: sed -i '/seccomp_filter=perf_event_open/d' /etc/default/grub && update-grub
generated artifact
/etc/ksl/seccomp_filter.conf# generated by kernel-surface-ledger - revert: kernel-surface-ledger revert { "defaultAction": "SCMP_ACT_ERRNO", "syscalls": [ {"name": "execve", "action": "SCMP_ACT_ALLOW"}, {"name": "exit", "action": "SCMP_ACT_ALLOW"}, {"name": "exit_group", "action": "SCMP_ACT_ALLOW"}, {"name": "rt_sigreturn", "action": "SCMP_ACT_ALLOW"}, {"name": "rt_sigaction", "action": "SCMP_ACT_ALLOW"}, {"name": "futex", "action": "SCMP_ACT_ALLOW"}, {"name": "restart_syscall", "action": "SCMP_ACT_ALLOW"}, {"name": "mmap", "action": "SCMP_ACT_ALLOW"}, {"name": "munmap", "action": "SCMP_ACT_ALLOW"}, {"name": "mprotect", "action": "SCMP_ACT_ALLOW"}, {"name": "brk", "action": "SCMP_ACT_ALLOW"}, {"name": "read", "action": "SCMP_ACT_ALLOW"}, {"name": "write", "action": "SCMP_ACT_ALLOW"}, {"name": "close", "action": "SCMP_ACT_ALLOW"} ] }generated for review — ksl never applies hardening itself
step 3sysctl_set
kernel.dmesg_restrict=1kernel.kptr_restrict=2kernel.modules_disabled=1kernel.unprivileged_userns_clone=0breakage: low5 CVEs killed−26 weightwhat could break
A container runtime such as Docker that relies on unprivileged user namespaces may fail to start containers.
detect it worked
detectionjournalctl -u docker | grep 'permission denied'revert
revertsysctl -w kernel.dmesg_restrict=0 kernel.kptr_restrict=0 kernel.modules_disabled=0 kernel.unprivileged_userns_clone=1check this — did step 3 work?
1the check shipped with this step
$ journalctl -u docker | grep 'permission denied'good: Output matches what the step describes — the change is in effect on this host.
not good: Empty or contradicting output means the change is not active yet. Apply the artifact, then run this again.
2sysctl kernel.dmesg_restrict is set
$ sysctl kernel.dmesg_restrictgood: The printed value is the restricted one from this step.
not good: A different value means the step is not applied on this host.
3sysctl kernel.kptr_restrict is set
$ sysctl kernel.kptr_restrictgood: The printed value is the restricted one from this step.
not good: A different value means the step is not applied on this host.
4sysctl kernel.modules_disabled is set
$ sysctl kernel.modules_disabledgood: The printed value is the restricted one from this step.
not good: A different value means the step is not applied on this host.
5sysctl kernel.unprivileged_userns_clone is set
$ sysctl kernel.unprivileged_userns_clonegood: The printed value is the restricted one from this step.
not good: A different value means the step is not applied on this host.
6nothing important broke
$ systemctl --failed --no-legend; journalctl -p err -b --since "10 min ago" | tail -20good: No failed units and no new kernel/service errors — the change was safe on this host.
not good: A failed unit or a new error right after the change is your signal to revert with: sysctl -w kernel.dmesg_restrict=0 kernel.kptr_restrict=0 kernel.modules_disabled=0 kernel.unprivileged_userns_clone=1
generated artifact
/etc/sysctl.d/99-ksl-hardening.conf# generated by kernel-surface-ledger - revert: sysctl -w kernel.dmesg_restrict=0 kernel.kptr_restrict=0 kernel.modules_disabled=0 kernel.unprivileged_userns_clone=1 # CVE-2016-5195: kernel.dmesg_restrict=1 # CVE-2016-5195: kernel.kptr_restrict=2 # CVE-2016-5195: kernel.modules_disabled=1 # CVE-2016-5195: kernel.unprivileged_userns_clone=0generated for review — ksl never applies hardening itself
step 4seccomp_filter
userfaultfdbreakage: none1 CVEs killedwhat could break
A checkpoint/restore tool such as CRIU that uses userfaultfd could be blocked by the seccomp filter.
detect it worked
detectionausearch -m seccomp -i | grep userfaultfdrevert
revertsudo rm -f /etc/seccomp.d/userfaultfd && sudo systemctl restart systemd-logindcheck this — did step 4 work?
1the check shipped with this step
$ ausearch -m seccomp -i | grep userfaultfdgood: Output matches what the step describes — the change is in effect on this host.
not good: Empty or contradicting output means the change is not active yet. Apply the artifact, then run this again.
2userfaultfd is gated by vm.unprivileged_userfaultfd
$ sysctl vm.unprivileged_userfaultfdgood: The value shown is the restricted one, so an ordinary user can no longer use userfaultfd.
not good: An unrestricted value means userfaultfd is still reachable by any local user. Re-apply the step's artifact.
3nothing important broke
$ systemctl --failed --no-legend; journalctl -p err -b --since "10 min ago" | tail -20good: No failed units and no new kernel/service errors — the change was safe on this host.
not good: A failed unit or a new error right after the change is your signal to revert with: sudo rm -f /etc/seccomp.d/userfaultfd && sudo systemctl restart systemd-logind
generated artifact
/etc/ksl/seccomp_filter.conf# generated by kernel-surface-ledger - revert: kernel-surface-ledger revert { "defaultAction": "SCMP_ACT_ERRNO", "syscalls": [ { "names": [ "execve", "exit", "exit_group", "rt_sigreturn", "rt_sigaction", "futex", "restart_syscall", "mmap", "munmap", "mprotect", "brk", "read", "write", "close" ], "action": "SCMP_ACT_ALLOW" } ] }generated for review — ksl never applies hardening itself
step 5seccomp_filter
io_uring_setupbreakage: low3 CVEs killedwhat could break
A workload using io_uring, such as fio, could fail to start io_uring contexts.
detect it worked
detectionausearch -m SECCOMP -i | grep io_uring_setuprevert
revertsed -i '/io_uring_setup/d' /etc/seccomp.d/default.profile && systemctl restart systemd-seccompcheck this — did step 5 work?
1the check shipped with this step
$ ausearch -m SECCOMP -i | grep io_uring_setupgood: Output matches what the step describes — the change is in effect on this host.
not good: Empty or contradicting output means the change is not active yet. Apply the artifact, then run this again.
2io_uring_setup is gated by kernel.io_uring_disabled
$ sysctl kernel.io_uring_disabledgood: The value shown is the restricted one, so an ordinary user can no longer use io_uring_setup.
not good: An unrestricted value means io_uring_setup is still reachable by any local user. Re-apply the step's artifact.
3nothing important broke
$ systemctl --failed --no-legend; journalctl -p err -b --since "10 min ago" | tail -20good: No failed units and no new kernel/service errors — the change was safe on this host.
not good: A failed unit or a new error right after the change is your signal to revert with: sed -i '/io_uring_setup/d' /etc/seccomp.d/default.profile && systemctl restart systemd-seccomp
generated artifact
/etc/ksl/seccomp_filter.conf# generated by kernel-surface-ledger - revert: kernel-surface-ledger revert { "defaultAction": "SCMP_ACT_ERRNO", "syscalls": [ { "names": [ "execve", "exit", "exit_group", "rt_sigreturn", "rt_sigaction", "futex", "restart_syscall", "mmap", "munmap", "mprotect", "brk", "read", "write", "close" ], "action": "SCMP_ACT_ALLOW" } ] }generated for review — ksl never applies hardening itself
05 / blast radius
Impact graph
Before you apply a step, see what it touches: each hardening step, the exact kernel surface it removes, and the kernel capability plus the user-space workloads that depend on that surface. Click any node to isolate its paths.
Edges come straight from the report: a step's targets, each target's subsystem, and the workloads whose touches include it. A target reaching only “no observed user” is orphaned surface — removing it broke nothing during the observation window.
06 / provenance
Where the AI is — and is not
The scoring engine is fully deterministic. The model explains and generates; it never decides.
what the model does
- Causal narration of each blame edge — why a workload needs this surface, what primitive an attacker gains, what the alternative is.(5 of 5 ledger rows narrated here)
- Artifact synthesis — applicable modprobe.d blacklists, per-service seccomp-BPF filters, systemd drop-ins, sysctl fragments.
- Breakage prediction — what could break, how to detect it, how to revert it.
what the model does not do
It never decides. Every weight, gate, debt figure, orphan set and plan ordering on this page comes from the deterministic engine. Disabling the model entirely produces byte-identical scored output — this is enforced by a test in the repository.
python ksl.py scan --raw fixtures/raw-demo.json --no-explain
python ksl.py check report.jsonCollector is strictly read-only: it never loads or unloads a module, never writes outside its output path, and degrades to a partial report as a non-root user. Report produced by ksl 0.1.0.