Skip to content

feat(skills): add controlled local and pinned publication - #524

Closed
SanAntonio021 wants to merge 2 commits into
SaladDay:mainfrom
SanAntonio021:pr/skills-controlled-publication
Closed

SanAntonio021 wants to merge 2 commits into
SaladDay:mainfrom
SanAntonio021:pr/skills-controlled-publication

Conversation

@SanAntonio021

@SanAntonio021 SanAntonio021 commented Oct 20, 2026 •

Copy link
Copy Markdown

Behavior

Add controlled skill publication from local directories and exact public Git commits. Local install/info commands provide JSON output; public install/update accept an exact source commit and retain their existing human-readable output.

Updates validate the SSOT and deployed copies before changing them, stage file changes with database updates, and provide rollback and recovery journals. Declared --runtime-file paths stay local to each copy: baseline comparisons do not open them, updates preserve them, and a conflicting source path is rejected before publication. Generated __pycache__/*.pyc files are excluded on both first pinned installation and updates; source directories containing only excluded caches are not deployed.

New installations record file and directory baselines, protecting user-added empty directories even when all application copies match the SSOT. First installs preserve existing empty trees and reject unregistered directory-to-file conversion. Subsequent updates keep retained directory projections consistent when application copies must be rebuilt. Native filename hashing preserves literal Unix backslashes and non-UTF8 names. Public pinned installs read the name and description from the captured source metadata. Baseline-owned empty directories can still become files. Old records retain a file-only baseline after updates and reject directory-to-file replacements because ownership of their existing directories cannot be established. Legacy marketplace hashes require a match against their original baseline and unchanged pre-existing hidden content before migration. Rollback restores directories created by an update to an existing installation so the update can be retried; external additions survive, and incomplete rollback retains recovery journals.

An OS file lock serializes skill mutations across CLI processes, including configuration import and snapshot restore, through baseline checks, publication, database commit, rollback, and cleanup. Publication captures the source once so metadata and every deployed copy use the same captured bytes even if the source changes during preparation.

Ordinary archive downloads and exact-commit downloads resolve the newly created, still-empty temporary root before writing downloaded content. This permits trusted system temp aliases such as macOS /var, while links inside skill trees remain rejected.

Skill commands bypass unrelated startup imports and proxy recovery while retaining the saved outbound proxy for downloads. This PR includes the publication and transaction APIs required by the runtime-file behavior. The comparison baseline is upstream v5.11.2 (b03e7258).

Local validation

Windows, Rust 1.91.1, MSVC 14.44 and Windows SDK 10.0.26100:

  • cargo fmt --check, git diff --check, cargo check --lib --no-default-features -j2, and cargo build --bin cc-switch -j2 passed.
  • 116 focused library tests passed: local publication (31), pinned updates (33), runtime paths (1), cross-process publication locking (6), in-place transactions (30), targeted publication including real HTTP downloads (14), and shared download temporary-root handling (1).
  • Eight CLI black-box checks passed. They cover installation, an update with exclusively locked runtime files, source-conflict rejection without filesystem/database changes, public-update argument validation, protection of added empty application directories, and two CLI processes waiting for the same OS lock before completing with consistent files and database state. Actual public pinned downloads are covered by the Rust HTTP tests; the CLI black-box public cases check argument validation.
  • The fork's maintenance commit 5ae10886b27d8f2d0d7eced8998bee94e74f7fdb also built successfully as a static-CRT Windows release, and that exact executable passed the same eight CLI black-box checks. Its eight fix files are identical to PR commit e38c24dd05b08c48aae02db2b0e132b5669726f5; the maintenance branch additionally retains the fork's existing proxy extensions. The release build and checks left all 13 monitored live files unchanged. Executable SHA256: 4f4bb13dce4c8f9cce5903fcc55b146f7d4322d963339a18f4c1b5a28831a007.
  • cargo clippy --all-targets -j2 -- -A clippy::reversed_empty_ranges passed with warnings. Unmodified Clippy is blocked by the existing reversed_empty_ranges diagnostic in src/cli/tui/ui/home_chart.rs:806.
  • The final validation run compared existence/content hashes of 13 live configuration files across focused tests, checks, the debug build, and CLI black-box checks; all final snapshots were unchanged. In an earlier run, a guard detected a live Claude settings change during a Cargo build (no tests were executing); validation stopped, retained the record and resumed with a fresh snapshot. Another earlier retry recorded a concurrent Claude plugin-usage counter update. No live files were restored or modified by the validation runner.
  • Unix-specific filename regression cases are included but were not executed on this Windows host.

Outstanding validation limits

This remains a draft. The full Windows suite is not green, and GitHub checks have not reported a passing result. CI is additional validation, not a substitute for local testing.

Runtime exclusions apply to the controlled publication invocation that explicitly supplies them. They are not persisted as a policy for later ordinary skills sync or provider-switch sync, whose full-tree behavior is unchanged. The publication lock also does not refresh another process's cached storage-location settings: changing skill storage while another process downloads a skill retains the pre-existing stale-location race. The concurrent CLI checks cover simultaneous controlled publication at a fixed storage location, not concurrent storage migration.

An earlier full-suite comparison recorded 4,383 passing / 139 failing library tests on this branch and 4,278 passing / 138 failing upstream. All 138 upstream library failures and all 46 other/integration failures also occurred on this branch. One additional library failure, store::tests::startup_seeds_gemini_common_config_snippet_from_live, has not been conclusively ruled out as a regression. The upstream comparison checkout needed two test-only Unix symlink calls gated with cfg(unix) to compile on Windows; production sources were unchanged.

The earlier full-suite attempt also exposed inadequate Windows home isolation: environment overrides alone did not redirect dirs::home_dir(), and tests touched live Gemini/OpenCode files. No further full-suite or store/configuration tests were run. Known Gemini provider, prompt, and authentication state was restored from available pre-test database records, and the generated OpenCode file was moved into private recovery storage. There was no complete pre-test Gemini file snapshot, so restoration of any additional manual Gemini settings cannot be verified. Recovery data and local validation artifacts are not included in this PR.

@SanAntonio021
SanAntonio021 marked this pull request as draft October 20, 2026 04:39
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