Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"
]
);
}
}
28 changes: 28 additions & 0 deletions tasks/TASK-2026-067-authorized-evolution-proposal-run/CONTEXT.md
Original file line number Diff line number Diff line change
@@ -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.
37 changes: 37 additions & 0 deletions tasks/TASK-2026-067-authorized-evolution-proposal-run/PRD.md
Original file line number Diff line number Diff line change
@@ -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 <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.
29 changes: 29 additions & 0 deletions tasks/TASK-2026-067-authorized-evolution-proposal-run/REVIEW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Review Report

## Scope Reviewed

- 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: 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`
- Security invariants: `pass`
- Required tests executed: `pass`
- Docs sync (EN/ZH): `pass`

## Test Evidence

- 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`
- Follow-up actions: None for this fix. Existing assistant warnings can be handled separately.
21 changes: 21 additions & 0 deletions tasks/TASK-2026-067-authorized-evolution-proposal-run/STATUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 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. Implemented a minimal fix so the background run passes `--proposal-id <authorized id>` and added `authorize_background_run_args_force_proposal`.
- Blockers: None.
- 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)
- [x] Implementation complete
- [x] Tests passed
- [x] Review complete
- [x] Board updated
51 changes: 51 additions & 0 deletions tasks/TASK-2026-067-authorized-evolution-proposal-run/TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# TASK Card

## Metadata

- Task ID: `TASK-2026-067`
- Title: Fix authorized evolution proposal run binding
- Status: `done`
- 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

- [x] Background runs started by `skilllite_authorize_capability_evolution` pass `--proposal-id <authorized 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

- 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 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

- 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.
3 changes: 2 additions & 1 deletion tasks/board.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 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 done)

## In Progress

Expand All @@ -17,6 +17,7 @@ Last updated: 2026-05-29 (TASK-2026-066 utf8 evolution log truncate done)

## 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`
Expand Down
Loading