From b546597a883287c03defca10942cada4d2fec483 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 4 Jun 2026 11:10:11 +0000 Subject: [PATCH 1/2] fix(assistant): force authorized evolution proposal runs Co-authored-by: EXboy --- .../integrations/evolution_ui/authorize.rs | 29 +++++++++-- .../CONTEXT.md | 28 ++++++++++ .../PRD.md | 37 ++++++++++++++ .../REVIEW.md | 29 +++++++++++ .../STATUS.md | 17 +++++++ .../TASK.md | 51 +++++++++++++++++++ tasks/board.md | 4 +- 7 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 tasks/TASK-2026-067-authorized-evolution-proposal-run/CONTEXT.md create mode 100644 tasks/TASK-2026-067-authorized-evolution-proposal-run/PRD.md create mode 100644 tasks/TASK-2026-067-authorized-evolution-proposal-run/REVIEW.md create mode 100644 tasks/TASK-2026-067-authorized-evolution-proposal-run/STATUS.md create mode 100644 tasks/TASK-2026-067-authorized-evolution-proposal-run/TASK.md diff --git a/crates/skilllite-assistant/src-tauri/src/skilllite_bridge/integrations/evolution_ui/authorize.rs b/crates/skilllite-assistant/src-tauri/src/skilllite_bridge/integrations/evolution_ui/authorize.rs index dd768382..e4ba89ca 100644 --- a/crates/skilllite-assistant/src-tauri/src/skilllite_bridge/integrations/evolution_ui/authorize.rs +++ b/crates/skilllite-assistant/src-tauri/src/skilllite_bridge/integrations/evolution_ui/authorize.rs @@ -2,9 +2,12 @@ use crate::skilllite_bridge::evolution_cli::spawn_skilllite_json; use crate::skilllite_bridge::local::engine_types::AuthorizeCapabilityResponse; -use crate::skilllite_bridge::local::env_keys::evolution as evo_keys; use crate::skilllite_bridge::paths::{find_project_root, load_dotenv_for_child}; +fn authorized_evolution_run_args(proposal_id: &str) -> Vec<&str> { + vec!["evolution", "run", "--json", "--proposal-id", proposal_id] +} + pub fn authorize_capability_evolution( workspace: &str, tool_name: &str, @@ -38,17 +41,33 @@ pub fn authorize_capability_evolution( let root = find_project_root(&workspace_owned); let mut cmd = std::process::Command::new(&skilllite_path_owned); crate::windows_spawn::hide_child_console(&mut cmd); - cmd.arg("evolution") - .arg("run") - .arg("--json") + cmd.args(authorized_evolution_run_args(&proposal_id_owned)) .current_dir(&root) .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()); for (k, v) in load_dotenv_for_child(&workspace_owned) { cmd.env(k, v); } - cmd.env(evo_keys::SKILLLITE_EVO_FORCE_PROPOSAL_ID, &proposal_id_owned); let _ = cmd.output(); }); Ok(proposal_id) } + +#[cfg(test)] +mod tests { + use super::authorized_evolution_run_args; + + #[test] + fn authorize_background_run_args_force_proposal() { + assert_eq!( + authorized_evolution_run_args("proposal_20260604_110000.000"), + vec![ + "evolution", + "run", + "--json", + "--proposal-id", + "proposal_20260604_110000.000" + ] + ); + } +} diff --git a/tasks/TASK-2026-067-authorized-evolution-proposal-run/CONTEXT.md b/tasks/TASK-2026-067-authorized-evolution-proposal-run/CONTEXT.md new file mode 100644 index 00000000..cdd5f507 --- /dev/null +++ b/tasks/TASK-2026-067-authorized-evolution-proposal-run/CONTEXT.md @@ -0,0 +1,28 @@ +# Technical Context + +## Current State + +- Relevant crates/files: `crates/skilllite-assistant/src-tauri/src/skilllite_bridge/integrations/evolution_ui/authorize.rs`, `crates/skilllite-commands/src/evolution.rs`, `crates/skilllite-evolution/src/run.rs`. +- Current behavior: `authorize.rs` enqueues a proposal, spawns `skilllite evolution run --json`, sets `SKILLLITE_EVO_FORCE_PROPOSAL_ID`, and discards output. `cmd_run` removes that env var when no `--proposal-id` argument is supplied, so `run_evolution_inner` does not load the authorized proposal. + +## Architecture Fit + +- Layer boundaries involved: desktop assistant UI bridge -> SkillLite CLI -> command crate -> evolution engine. +- Interfaces to preserve: Tauri command shape, `skilllite evolution authorize-capability`, `skilllite evolution run --proposal-id`, and workspace dotenv merging. + +## Dependency and Compatibility + +- New dependencies: none. +- Backward compatibility notes: existing callers that set `--proposal-id` are unchanged; this fix aligns the authorization background caller with the supported CLI argument. + +## Design Decisions + +- Decision: pass `--proposal-id` in the background subprocess argument list and keep env propagation harmless. + - Rationale: `cmd_run` treats the CLI argument as the authoritative way to force a proposal and scopes the environment variable safely around execution. + - Alternatives considered: modify `cmd_run` to preserve a pre-existing env var when no CLI argument is passed. + - Why rejected: preserving ambient env would broaden the force semantics for all CLI callers and risk unexpected forced runs from inherited process environments. + +## Open Questions + +- [x] Is a docs update required? No, this restores the existing documented command behavior and does not change user-facing command syntax. +- [x] Is a database migration required? No. diff --git a/tasks/TASK-2026-067-authorized-evolution-proposal-run/PRD.md b/tasks/TASK-2026-067-authorized-evolution-proposal-run/PRD.md new file mode 100644 index 00000000..121fdf78 --- /dev/null +++ b/tasks/TASK-2026-067-authorized-evolution-proposal-run/PRD.md @@ -0,0 +1,37 @@ +# PRD + +## Background + +Recent desktop split work moved authorized capability evolution to a CLI subprocess. The CLI supports forcing a backlog proposal with `--proposal-id`, and `cmd_run` intentionally scopes the force environment variable around that explicit argument. The desktop authorization path did not pass the argument, so the authorized proposal id could be lost before `run_evolution` selected work. + +## Objective + +When a user starts evolution from the chat capability prompt, the immediately spawned background run must target the exact proposal id returned by `authorize-capability`. + +## Functional Requirements + +- FR-1: The authorization background process must include `--proposal-id` followed by the authorized proposal id. +- FR-2: Existing `.env` and child environment merging must continue to work. +- FR-3: Manual evolution triggering remains unchanged. + +## Non-Functional Requirements + +- Security: Do not bypass coordinator policy runtime or auto-approve dangerous evolution; only preserve target selection. +- Performance: No additional process or database work beyond the existing background run. +- Compatibility: Preserve the existing `skilllite evolution run --proposal-id` CLI contract and current desktop API shape. + +## Constraints + +- Technical: Keep the fix local to the desktop bridge unless runtime evidence shows the CLI contract itself is broken. +- Timeline: N/A for automation execution; complete within this investigation branch. + +## Success Metrics + +- Metric: authorization background run argument list. +- Baseline: `skilllite evolution run --json` with only `SKILLLITE_EVO_FORCE_PROPOSAL_ID`. +- Target: `skilllite evolution run --json --proposal-id `, with optional environment also harmless. + +## Rollout + +- Rollout plan: ship as a focused bug-fix PR. +- Rollback plan: revert the assistant bridge argument helper if unexpected subprocess behavior appears. diff --git a/tasks/TASK-2026-067-authorized-evolution-proposal-run/REVIEW.md b/tasks/TASK-2026-067-authorized-evolution-proposal-run/REVIEW.md new file mode 100644 index 00000000..e5fd29ef --- /dev/null +++ b/tasks/TASK-2026-067-authorized-evolution-proposal-run/REVIEW.md @@ -0,0 +1,29 @@ +# Review Report + +## Scope Reviewed + +- Files/modules: +- Commits/changes: + +## Findings + +- Critical: +- Major: +- Minor: + +## Quality Gates + +- Architecture boundary checks: `pass | fail` +- Security invariants: `pass | fail` +- Required tests executed: `pass | fail` +- Docs sync (EN/ZH): `pass | fail` + +## Test Evidence + +- Commands run: +- Key outputs: + +## Decision + +- Merge readiness: `ready | not ready` +- Follow-up actions: diff --git a/tasks/TASK-2026-067-authorized-evolution-proposal-run/STATUS.md b/tasks/TASK-2026-067-authorized-evolution-proposal-run/STATUS.md new file mode 100644 index 00000000..e60d7cb7 --- /dev/null +++ b/tasks/TASK-2026-067-authorized-evolution-proposal-run/STATUS.md @@ -0,0 +1,17 @@ +# Status Journal + +## Timeline + +- 2026-06-04: + - Progress: Identified that desktop authorized capability evolution spawns `skilllite evolution run --json` without `--proposal-id`, while `cmd_run` clears the force env var when the CLI argument is absent. + - Blockers: None. + - Next step: Implement the minimal assistant bridge fix and add a regression test for the subprocess args. + +## Checkpoints + +- [x] PRD drafted before implementation (or `N/A` recorded) +- [x] Context drafted before implementation (or `N/A` recorded) +- [ ] Implementation complete +- [ ] Tests passed +- [ ] Review complete +- [ ] Board updated diff --git a/tasks/TASK-2026-067-authorized-evolution-proposal-run/TASK.md b/tasks/TASK-2026-067-authorized-evolution-proposal-run/TASK.md new file mode 100644 index 00000000..56a91da7 --- /dev/null +++ b/tasks/TASK-2026-067-authorized-evolution-proposal-run/TASK.md @@ -0,0 +1,51 @@ +# TASK Card + +## Metadata + +- Task ID: `TASK-2026-067` +- Title: Fix authorized evolution proposal run binding +- Status: `in_progress` +- Priority: `P1` +- Owner: `agent` +- Contributors: `automation` +- Created: `2026-06-04` +- Target milestone: recent critical bug investigation + +## Problem + +Desktop chat authorization for capability evolution enqueues a concrete backlog proposal and then starts a background `skilllite evolution run`. The background run only sets `SKILLLITE_EVO_FORCE_PROPOSAL_ID`, but `cmd_run` clears that environment variable whenever no `--proposal-id` CLI argument is present. As a result, the user-authorized proposal may remain queued while the background run sees no forced proposal and either does nothing or selects a different candidate. + +## Scope + +- In scope: bind the authorized background evolution run to the returned proposal id using the existing `--proposal-id` CLI contract. +- In scope: add a focused regression test for the background argument construction. +- Out of scope: changing evolution policy runtime decisions, backlog schema, or LLM synthesis behavior. + +## Acceptance Criteria + +- [ ] Background runs started by `skilllite_authorize_capability_evolution` pass `--proposal-id `. +- [ ] The forced proposal environment variable is no longer the only binding mechanism for this path. +- [ ] Tests cover the argument contract and the affected crates still pass required checks. + +## Risks + +- Risk: argument construction diverges from manual trigger behavior again. + - Impact: authorized proposals can be skipped or unrelated proposals can execute. + - Mitigation: centralize the authorization background run args in a small helper with a regression test. + +## Validation Plan + +- Required tests: targeted Rust tests for the assistant bridge and workspace Rust tests. +- Commands to run: `cargo fmt --check`; `cargo test --manifest-path crates/skilllite-assistant/src-tauri/Cargo.toml authorize_background_run_args_force_proposal`; `cargo test -p skilllite-commands`; `cargo test`. +- Manual checks: inspect the final `authorize.rs` command chain to confirm the child receives `--proposal-id`. + +## Regression Scope + +- Areas likely affected: desktop chat "start evolution" action, desktop evolution CLI bridge, `skilllite evolution run` proposal forcing. +- Explicit non-goals: policy runtime thresholds, proposal recovery, queue selection, and UI copy. + +## Links + +- Source TODO section: N/A, triggered by automated recent-commit bug investigation. +- Related PRs/issues: recent P2 desktop/CLI split commits. +- Related docs: N/A, this restores documented CLI behavior without changing user-facing commands. diff --git a/tasks/board.md b/tasks/board.md index 43428f7b..5ca32dfa 100644 --- a/tasks/board.md +++ b/tasks/board.md @@ -1,10 +1,10 @@ # Task Board -Last updated: 2026-05-29 (TASK-2026-066 utf8 evolution log truncate done) +Last updated: 2026-06-04 (TASK-2026-067 authorized evolution proposal run in progress) ## In Progress -- None. +- `TASK-2026-067-authorized-evolution-proposal-run` - Status: `in_progress` - Owner: `agent` ## Ready From 52a2c0af75f29a91e2b33bc080f188196cadba65 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 4 Jun 2026 11:17:38 +0000 Subject: [PATCH 2/2] docs(task): record authorized evolution validation Co-authored-by: EXboy --- .../REVIEW.md | 26 +++++++++---------- .../STATUS.md | 16 +++++++----- .../TASK.md | 12 ++++----- tasks/board.md | 5 ++-- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/tasks/TASK-2026-067-authorized-evolution-proposal-run/REVIEW.md b/tasks/TASK-2026-067-authorized-evolution-proposal-run/REVIEW.md index e5fd29ef..64783766 100644 --- a/tasks/TASK-2026-067-authorized-evolution-proposal-run/REVIEW.md +++ b/tasks/TASK-2026-067-authorized-evolution-proposal-run/REVIEW.md @@ -2,28 +2,28 @@ ## Scope Reviewed -- Files/modules: -- Commits/changes: +- Files/modules: desktop authorized evolution bridge, `skilllite evolution run` proposal forcing, task artifacts. +- Commits/changes: recent P2 desktop/CLI split path and this bug-fix branch. ## Findings -- Critical: -- Major: -- Minor: +- Critical: None. +- Major: Active bug fixed. `skilllite_authorize_capability_evolution` returned a proposal id to the UI, then spawned a background run without `--proposal-id`. `cmd_run` removed `SKILLLITE_EVO_FORCE_PROPOSAL_ID` when no CLI proposal id was present, so the authorized backlog proposal was not forced. +- Minor: Assistant crate still emits pre-existing warnings during plain `cargo test` / `cargo clippy`; they are unrelated to this change. ## Quality Gates -- Architecture boundary checks: `pass | fail` -- Security invariants: `pass | fail` -- Required tests executed: `pass | fail` -- Docs sync (EN/ZH): `pass | fail` +- Architecture boundary checks: `pass` +- Security invariants: `pass` +- Required tests executed: `pass` +- Docs sync (EN/ZH): `pass` ## Test Evidence -- Commands run: -- Key outputs: +- Commands run: `cargo fmt --check`; `cargo test --manifest-path crates/skilllite-assistant/src-tauri/Cargo.toml authorize_background_run_args_force_proposal`; `cargo test --manifest-path crates/skilllite-assistant/src-tauri/Cargo.toml`; `cargo clippy --manifest-path crates/skilllite-assistant/src-tauri/Cargo.toml --all-targets`; `cargo test -p skilllite-commands`; `cargo clippy --all-targets -- -D warnings`; `cargo test`; `python3 scripts/validate_tasks.py`. +- Key outputs: targeted assistant regression test: `1 passed`; full assistant tests: `51 passed`; `skilllite-commands`: `23 passed`; workspace clippy finished successfully with `-D warnings`; workspace test suite passed; task validation passed for 67 task directories. ## Decision -- Merge readiness: `ready | not ready` -- Follow-up actions: +- Merge readiness: `ready` +- Follow-up actions: None for this fix. Existing assistant warnings can be handled separately. diff --git a/tasks/TASK-2026-067-authorized-evolution-proposal-run/STATUS.md b/tasks/TASK-2026-067-authorized-evolution-proposal-run/STATUS.md index e60d7cb7..b168b8ef 100644 --- a/tasks/TASK-2026-067-authorized-evolution-proposal-run/STATUS.md +++ b/tasks/TASK-2026-067-authorized-evolution-proposal-run/STATUS.md @@ -3,15 +3,19 @@ ## Timeline - 2026-06-04: - - Progress: Identified that desktop authorized capability evolution spawns `skilllite evolution run --json` without `--proposal-id`, while `cmd_run` clears the force env var when the CLI argument is absent. + - Progress: Identified that desktop authorized capability evolution spawns `skilllite evolution run --json` without `--proposal-id`, while `cmd_run` clears the force env var when the CLI argument is absent. Implemented a minimal fix so the background run passes `--proposal-id ` and added `authorize_background_run_args_force_proposal`. - Blockers: None. - - Next step: Implement the minimal assistant bridge fix and add a regression test for the subprocess args. + - Next step: Done after validation. +- 2026-06-04: + - Progress: Validation passed: `cargo fmt --check`; targeted assistant regression test; full assistant tests; assistant clippy; `cargo test -p skilllite-commands`; workspace clippy with `-D warnings`; workspace `cargo test`; task validation. + - Blockers: None. + - Next step: PR ready. ## Checkpoints - [x] PRD drafted before implementation (or `N/A` recorded) - [x] Context drafted before implementation (or `N/A` recorded) -- [ ] Implementation complete -- [ ] Tests passed -- [ ] Review complete -- [ ] Board updated +- [x] Implementation complete +- [x] Tests passed +- [x] Review complete +- [x] Board updated diff --git a/tasks/TASK-2026-067-authorized-evolution-proposal-run/TASK.md b/tasks/TASK-2026-067-authorized-evolution-proposal-run/TASK.md index 56a91da7..a891f098 100644 --- a/tasks/TASK-2026-067-authorized-evolution-proposal-run/TASK.md +++ b/tasks/TASK-2026-067-authorized-evolution-proposal-run/TASK.md @@ -4,7 +4,7 @@ - Task ID: `TASK-2026-067` - Title: Fix authorized evolution proposal run binding -- Status: `in_progress` +- Status: `done` - Priority: `P1` - Owner: `agent` - Contributors: `automation` @@ -23,9 +23,9 @@ Desktop chat authorization for capability evolution enqueues a concrete backlog ## Acceptance Criteria -- [ ] Background runs started by `skilllite_authorize_capability_evolution` pass `--proposal-id `. -- [ ] The forced proposal environment variable is no longer the only binding mechanism for this path. -- [ ] Tests cover the argument contract and the affected crates still pass required checks. +- [x] Background runs started by `skilllite_authorize_capability_evolution` pass `--proposal-id `. +- [x] The forced proposal environment variable is no longer the only binding mechanism for this path. +- [x] Tests cover the argument contract and the affected crates still pass required checks. ## Risks @@ -36,8 +36,8 @@ Desktop chat authorization for capability evolution enqueues a concrete backlog ## Validation Plan - Required tests: targeted Rust tests for the assistant bridge and workspace Rust tests. -- Commands to run: `cargo fmt --check`; `cargo test --manifest-path crates/skilllite-assistant/src-tauri/Cargo.toml authorize_background_run_args_force_proposal`; `cargo test -p skilllite-commands`; `cargo test`. -- Manual checks: inspect the final `authorize.rs` command chain to confirm the child receives `--proposal-id`. +- Commands run: `cargo fmt --check`; `cargo test --manifest-path crates/skilllite-assistant/src-tauri/Cargo.toml authorize_background_run_args_force_proposal`; `cargo test --manifest-path crates/skilllite-assistant/src-tauri/Cargo.toml`; `cargo clippy --manifest-path crates/skilllite-assistant/src-tauri/Cargo.toml --all-targets`; `cargo test -p skilllite-commands`; `cargo clippy --all-targets -- -D warnings`; `cargo test`; `python3 scripts/validate_tasks.py`. +- Manual checks: inspected the final `authorize.rs` command chain and confirmed the child receives `--proposal-id`. ## Regression Scope diff --git a/tasks/board.md b/tasks/board.md index 5ca32dfa..6380bea7 100644 --- a/tasks/board.md +++ b/tasks/board.md @@ -1,10 +1,10 @@ # Task Board -Last updated: 2026-06-04 (TASK-2026-067 authorized evolution proposal run in progress) +Last updated: 2026-06-04 (TASK-2026-067 authorized evolution proposal run done) ## In Progress -- `TASK-2026-067-authorized-evolution-proposal-run` - Status: `in_progress` - Owner: `agent` +- None. ## Ready @@ -17,6 +17,7 @@ Last updated: 2026-06-04 (TASK-2026-067 authorized evolution proposal run in pro ## Done +- `TASK-2026-067-authorized-evolution-proposal-run` - Status: `done` - Owner: `agent` - `TASK-2026-066-utf8-evolution-log-truncate` - Status: `done` - Owner: `agent` - `TASK-2026-064-env-keys-single-source` - Status: `done` - Owner: `agent` - `TASK-2026-063-extension-tool-metadata-dispatch` - Status: `done` - Owner: `agent`