diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index e5852d99..3680e9dd 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "sysknife", - "version": "0.13.1", + "version": "0.14.0", "description": "Linux sysadmin co-pilot as an MCP server: plain-language requests become typed, risk-classified actions that a privileged daemon runs only after out-of-band terminal approval, with an Ed25519-signed audit chain and automatic rollback.", "repository": "https://github.com/lacs-project/sysknife", "homepage": "https://lacs-project.github.io/sysknife/", diff --git a/CHANGELOG.md b/CHANGELOG.md index 68c397f3..f554b7da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,20 @@ Releases before `0.2.5` predate the public launch; their notes live in the ## [Unreleased] +## [0.14.0] — 2026-09-07 + +The middle digit moves because an exit code changed. `sysknife audit checkpoint` +with no database configured returned 2 and now returns 4, and an exit code is +the contract a wrapper script reads. Nothing was removed and no signature +changed; under the rule in [docs/release.md](docs/release.md#version-numbering) +that is still a compatibility break, the same way v0.9.0 was when +`sysknife-setup` began refusing a malformed `.mcp.json` it used to overwrite. + +Two of these are security fixes in the daemon's authorization path. A cancelled +transaction could keep a live approval receipt, and a peer the kernel could not +pin was still credited with the supplementary groups of whatever process held +that PID by the time `/proc` was read. + ### Changed - **A CLI timeout no longer reports that an action ran, and a missing diff --git a/Cargo.lock b/Cargo.lock index 133758fb..ac0d471c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4811,7 +4811,7 @@ dependencies = [ [[package]] name = "sysknife-brain" -version = "0.13.1" +version = "0.14.0" dependencies = [ "async-openai", "async-trait", @@ -4833,7 +4833,7 @@ dependencies = [ [[package]] name = "sysknife-cli" -version = "0.13.1" +version = "0.14.0" dependencies = [ "assert_cmd", "chrono", @@ -4863,7 +4863,7 @@ dependencies = [ [[package]] name = "sysknife-core" -version = "0.13.1" +version = "0.14.0" dependencies = [ "serde", "tempfile", @@ -4872,7 +4872,7 @@ dependencies = [ [[package]] name = "sysknife-daemon" -version = "0.13.1" +version = "0.14.0" dependencies = [ "async-trait", "chrono", @@ -4900,7 +4900,7 @@ dependencies = [ [[package]] name = "sysknife-daemon-test" -version = "0.13.1" +version = "0.14.0" dependencies = [ "serde_json", "sysknife-daemon", @@ -4909,7 +4909,7 @@ dependencies = [ [[package]] name = "sysknife-proto" -version = "0.13.1" +version = "0.14.0" dependencies = [ "prost", "prost-build", @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "sysknife-shell" -version = "0.13.1" +version = "0.14.0" dependencies = [ "async-trait", "reqwest 0.12.28", @@ -4935,7 +4935,7 @@ dependencies = [ [[package]] name = "sysknife-types" -version = "0.13.1" +version = "0.14.0" dependencies = [ "prost", "serde", diff --git a/apps/sysknife-cli/Cargo.toml b/apps/sysknife-cli/Cargo.toml index 20b88ffc..d874303a 100644 --- a/apps/sysknife-cli/Cargo.toml +++ b/apps/sysknife-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sysknife-cli" -version = "0.13.1" +version = "0.14.0" edition.workspace = true license.workspace = true repository.workspace = true @@ -15,12 +15,12 @@ name = "sysknife" path = "src/main.rs" [dependencies] -sysknife-brain = { path = "../../crates/sysknife-brain", version = "0.13.1" } -sysknife-core = { path = "../../crates/sysknife-core", version = "0.13.1" } -sysknife-daemon = { path = "../../crates/sysknife-daemon", version = "0.13.1" } +sysknife-brain = { path = "../../crates/sysknife-brain", version = "0.14.0" } +sysknife-core = { path = "../../crates/sysknife-core", version = "0.14.0" } +sysknife-daemon = { path = "../../crates/sysknife-daemon", version = "0.14.0" } chrono = "0.4" libc = "0.2" -sysknife-types = { path = "../../crates/sysknife-types", version = "0.13.1" } +sysknife-types = { path = "../../crates/sysknife-types", version = "0.14.0" } clap = { version = "4", features = ["derive"] } clap_complete = "4" @@ -40,11 +40,11 @@ tokio-vsock = "0.7.2" [dev-dependencies] # `test-support` unlocks `Plan::assume_authorized` for tests only. -sysknife-brain = { path = "../../crates/sysknife-brain", version = "0.13.1", features = ["test-support"] } +sysknife-brain = { path = "../../crates/sysknife-brain", version = "0.14.0", features = ["test-support"] } # and `AttributionCensus::from_counts_for_tests`, so the verify renderers can be # tested without building signed chain rows. Dev-only: production builds of this # bin do not compile dev-dependencies, so the constructor stays unreachable there. -sysknife-daemon = { path = "../../crates/sysknife-daemon", version = "0.13.1", features = ["test-support"] } +sysknife-daemon = { path = "../../crates/sysknife-daemon", version = "0.14.0", features = ["test-support"] } assert_cmd = "2" predicates = "3" tempfile = "3" diff --git a/apps/sysknife-shell/package-lock.json b/apps/sysknife-shell/package-lock.json index c34672c6..8af18096 100644 --- a/apps/sysknife-shell/package-lock.json +++ b/apps/sysknife-shell/package-lock.json @@ -1,12 +1,12 @@ { "name": "sysknife-shell", - "version": "0.13.1", + "version": "0.14.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sysknife-shell", - "version": "0.13.1", + "version": "0.14.0", "dependencies": { "@tauri-apps/api": "^2.4.1", "react": "^19.2.8", diff --git a/apps/sysknife-shell/package.json b/apps/sysknife-shell/package.json index 9db99e4b..044fab58 100644 --- a/apps/sysknife-shell/package.json +++ b/apps/sysknife-shell/package.json @@ -1,7 +1,7 @@ { "name": "sysknife-shell", "private": true, - "version": "0.13.1", + "version": "0.14.0", "type": "module", "scripts": { "dev": "vite", diff --git a/apps/sysknife-shell/src-tauri/Cargo.toml b/apps/sysknife-shell/src-tauri/Cargo.toml index 3af1b58f..6ae074d9 100644 --- a/apps/sysknife-shell/src-tauri/Cargo.toml +++ b/apps/sysknife-shell/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sysknife-shell" -version = "0.13.1" +version = "0.14.0" edition.workspace = true license.workspace = true repository.workspace = true @@ -14,8 +14,8 @@ default = ["demo"] demo = [] [dependencies] -sysknife-brain = { path = "../../../crates/sysknife-brain", version = "0.13.1" } -sysknife-core = { path = "../../../crates/sysknife-core", version = "0.13.1" } +sysknife-brain = { path = "../../../crates/sysknife-brain", version = "0.14.0" } +sysknife-core = { path = "../../../crates/sysknife-core", version = "0.14.0" } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } tauri = { version = "2.5.6" } diff --git a/apps/sysknife-shell/src-tauri/tauri.conf.json b/apps/sysknife-shell/src-tauri/tauri.conf.json index b0e8f1ac..636c1566 100644 --- a/apps/sysknife-shell/src-tauri/tauri.conf.json +++ b/apps/sysknife-shell/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "identifier": "org.lacsfoundation.LacsShell", "productName": "SysKnife Shell", - "version": "0.13.1", + "version": "0.14.0", "build": { "beforeDevCommand": "pnpm dev", "beforeBuildCommand": "pnpm build", diff --git a/crates/sysknife-brain/Cargo.toml b/crates/sysknife-brain/Cargo.toml index e69d7ec0..b2dc176b 100644 --- a/crates/sysknife-brain/Cargo.toml +++ b/crates/sysknife-brain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sysknife-brain" -version = "0.13.1" +version = "0.14.0" edition.workspace = true license.workspace = true repository.workspace = true @@ -18,8 +18,8 @@ test-support = [] [dependencies] async-trait = { workspace = true } futures = "0.3" -sysknife-core = { path = "../sysknife-core", version = "0.13.1" } -sysknife-types = { path = "../sysknife-types", version = "0.13.1" } +sysknife-core = { path = "../sysknife-core", version = "0.14.0" } +sysknife-types = { path = "../sysknife-types", version = "0.14.0" } async-openai = { version = "0.41", features = ["chat-completion"] } # rig-core 0.40 renamed its lib crate `rig` -> `rig_core`; alias it back to `rig` # so existing `use rig::...` paths keep working. diff --git a/crates/sysknife-core/Cargo.toml b/crates/sysknife-core/Cargo.toml index 8183bf17..f2f3c949 100644 --- a/crates/sysknife-core/Cargo.toml +++ b/crates/sysknife-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sysknife-core" -version = "0.13.1" +version = "0.14.0" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/crates/sysknife-daemon-test/Cargo.toml b/crates/sysknife-daemon-test/Cargo.toml index d7869543..a725c5ed 100644 --- a/crates/sysknife-daemon-test/Cargo.toml +++ b/crates/sysknife-daemon-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sysknife-daemon-test" -version = "0.13.1" +version = "0.14.0" publish = false edition.workspace = true license.workspace = true @@ -13,6 +13,6 @@ name = "sysknife-daemon-test" path = "src/main.rs" [dependencies] -sysknife-daemon = { path = "../sysknife-daemon", version = "0.13.1" } +sysknife-daemon = { path = "../sysknife-daemon", version = "0.14.0" } serde_json = { workspace = true } tokio = { workspace = true } diff --git a/crates/sysknife-daemon/Cargo.toml b/crates/sysknife-daemon/Cargo.toml index 5883b687..3d12ea84 100644 --- a/crates/sysknife-daemon/Cargo.toml +++ b/crates/sysknife-daemon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sysknife-daemon" -version = "0.13.1" +version = "0.14.0" edition.workspace = true license.workspace = true repository.workspace = true @@ -17,8 +17,8 @@ categories = ["command-line-utilities", "os::linux-apis"] test-support = [] [dependencies] -sysknife-core = { path = "../sysknife-core", version = "0.13.1" } -sysknife-types = { path = "../sysknife-types", version = "0.13.1" } +sysknife-core = { path = "../sysknife-core", version = "0.14.0" } +sysknife-types = { path = "../sysknife-types", version = "0.14.0" } rusqlite = { version = "0.40", features = ["bundled"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } @@ -61,7 +61,7 @@ sqlx-postgres = { version = "0.9", default-features = false, features = [ chrono = { version = "0.4", features = ["serde"] } [dev-dependencies] -sysknife-brain = { path = "../sysknife-brain", version = "0.13.1" } +sysknife-brain = { path = "../sysknife-brain", version = "0.14.0" } # `test-util` provides the paused test clock, so deadline tests assert on the # timer firing instead of sleeping for the real duration. tokio = { version = "1", features = ["test-util"] } diff --git a/crates/sysknife-proto/Cargo.toml b/crates/sysknife-proto/Cargo.toml index 8c19b10b..d13d6e3d 100644 --- a/crates/sysknife-proto/Cargo.toml +++ b/crates/sysknife-proto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sysknife-proto" -version = "0.13.1" +version = "0.14.0" edition = "2021" build = "build.rs" license.workspace = true diff --git a/crates/sysknife-types/Cargo.toml b/crates/sysknife-types/Cargo.toml index 05e9dc77..95c09029 100644 --- a/crates/sysknife-types/Cargo.toml +++ b/crates/sysknife-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sysknife-types" -version = "0.13.1" +version = "0.14.0" edition.workspace = true license.workspace = true repository.workspace = true @@ -10,7 +10,7 @@ keywords = ["llm", "ai-agent", "linux", "actions", "types"] categories = ["command-line-utilities", "os::linux-apis"] [dependencies] -sysknife-proto = { path = "../sysknife-proto", version = "0.13.1" } +sysknife-proto = { path = "../sysknife-proto", version = "0.14.0" } serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } diff --git a/packages/setup/package.json b/packages/setup/package.json index 9ed30ca8..62089a8e 100644 --- a/packages/setup/package.json +++ b/packages/setup/package.json @@ -1,6 +1,6 @@ { "name": "sysknife-setup", - "version": "0.13.1", + "version": "0.14.0", "description": "Zero-friction setup for SysKnife MCP server \u2014 Claude Code, Cursor, and Codex CLI", "author": "Vladimir Rotariu", "repository": { diff --git a/server.json b/server.json index 51dca074..9458b844 100644 --- a/server.json +++ b/server.json @@ -3,7 +3,7 @@ "name": "io.github.lacs-project/sysknife", "title": "SysKnife", "description": "Administers Linux via typed, approval-gated actions with an Ed25519-signed audit trail.", - "version": "0.13.1", + "version": "0.14.0", "websiteUrl": "https://lacs-project.github.io/sysknife/", "repository": { "url": "https://github.com/lacs-project/sysknife", @@ -23,7 +23,7 @@ "registryType": "cargo", "registryBaseUrl": "https://crates.io", "identifier": "sysknife-cli", - "version": "0.13.1", + "version": "0.14.0", "transport": { "type": "stdio" },