- 2826
r#"{"name":"team","plugins":[{"name":"tool","source":"./tool"}]}"#, - 2827
); - 2828
write( - 2829
&catalog.path().join("tool/vak-plugin.json"), - 2830
r#"{"schema":1,"name":"tool","version":"1.0.0","description":"Tool","license":"MIT"}"#, - 2831
); - 2832
let inspection = inspect_catalog(catalog.path()).unwrap(); - 2833
let local = materialize_catalog_entry( - 2834
catalog.path(), - 2835
&inspection.entries[0], - 2836
&catalog.path().join("downloads"), - 2837
) - 2838
.unwrap(); - 2839
assert!(local.ends_with("tool")); - 2840
let remote = CatalogEntry { - 2841
name: "remote".into(), - 2842
source: serde_json::json!("https://github.com/acme/tool.git"), - 2843
version: None, - 2844
description: None, - 2845
license: None, - 2846
}; - 2847
assert!(matches!( - 2848
materialize_catalog_entry(catalog.path(), &remote, &catalog.path().join("downloads")), - 2849
Err(PluginError::UnsafePackage(_)) - 2850
)); - 2851
} - 2852
- 2853
#[test] - 2854
fn signature_verification_rejects_malformed_or_wrong_evidence() { - 2855
assert!(matches!( - 2856
verify_ed25519_signature(b"catalog", "not-base64", "not-base64"), - 2857
Err(PluginError::UnsafePackage(_)) - 2858
)); - 2859
let key = base64::engine::general_purpose::STANDARD.encode([0u8; 32]); - 2860
let sig = base64::engine::general_purpose::STANDARD.encode([0u8; 64]); - 2861
assert!(matches!( - 2862
verify_ed25519_signature(b"catalog", &key, &sig), - 2863
Err(PluginError::UnsafePackage(_)) - 2864
)); - 2865
} - 2866
- 2867
#[test] - 2868
fn retired_plugin_scan_detects_references_to_retired_tools() { - 2869
let temp = tempfile::tempdir().unwrap(); - 2870
// Build a plugin package that references `python_eval` in its skill - 2871
// description — the exact pattern that caused the hallucination. - 2872
write( - 2873
&temp.path().join("vak-plugin.json"), - 2874
r#"{ - 2875
"schema": 1, - 2876
"name": "legacy-python", - 2877
"version": "1.0.0", - 2878
"description": "Legacy", - 2879
"license": "MIT", - 2880
"components": {"skills": ["skills"]} - 2881
}"#, - 2882
); - 2883
write( - 2884
&temp.path().join("skills/python-exec/SKILL.md"), - 2885
"---\nname: python-exec\ndescription: Execute Python using the `python_eval` tool.\n---\nAlways use `python_eval`.\n", - 2886
); - 2887
let store = PluginStore::new(temp.path()); - 2888
store - 2889
.install_local( - 2890
temp.path(), - 2891
InstallOptions { - 2892
scope: InstallScope::Workspace, - 2893
allow_unlicensed: false, - 2894
}, - 2895
) - 2896
.unwrap(); - 2897
store.enable("legacy-python").unwrap(); - 2898
let flagged = store.retired_plugins().unwrap(); - 2899
assert_eq!(flagged.len(), 1); - 2900
assert_eq!(flagged[0].0, "legacy-python"); - 2901
assert!(flagged[0].1.contains(&"python_eval".to_string())); - 2902
} - 2903
- 2904
#[test] - 2905
fn clean_plugin_is_not_flagged_as_retired() { - 2906
let temp = tempfile::tempdir().unwrap(); - 2907
package(temp.path()); - 2908
let store = PluginStore::new(temp.path()); - 2909
store - 2910
.install_local( - 2911
temp.path(), - 2912
InstallOptions { - 2913
scope: InstallScope::Workspace, - 2914
allow_unlicensed: false, - 2915
}, - 2916
) - 2917
.unwrap(); - 2918
store.enable("daily-brief").unwrap(); - 2919
let flagged = store.retired_plugins().unwrap(); - 2920
assert!(flagged.is_empty()); - 2921
} - 2922
} - 2923
Indexing the workspace…
Vakyartha documentation is discovering safe artifacts, anchors, and source references.