Skip to main content

aidens_profile_coding/
lib.rs

1//! Coding-agent profile expansion.
2
3use aidens_contracts::{
4    AiDENsAppPlanV1, CanonicalToolSideEffectClass, MemoryModeV1, ReportLevelV1, RiskDisclosureV1,
5};
6
7pub const PROFILE_ID: &str = "coding-agent";
8pub const SUPPORT_TIER: &str = "supported-local";
9pub const NON_GOAL: &str = "not production cloud or broad autonomy";
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct ProfileCodingStatus {
13    pub enabled: bool,
14    pub note: String,
15}
16
17impl Default for ProfileCodingStatus {
18    fn default() -> Self {
19        Self {
20            enabled: true,
21            note: format!(
22                "{PROFILE_ID}: {SUPPORT_TIER}; risky actions require explicit permits; {NON_GOAL}"
23            ),
24        }
25    }
26}
27
28pub fn coding_agent_plan(app_id: impl Into<String>) -> AiDENsAppPlanV1 {
29    AiDENsAppPlanV1 {
30        app_id: app_id.into(),
31        profile_id: PROFILE_ID.into(),
32        provider_required: true,
33        memory_mode: MemoryModeV1::Optional,
34        receipt_level: ReportLevelV1::Full,
35        dangerous_auto_approval: false,
36        risk_disclosures: [
37            (
38                CanonicalToolSideEffectClass::Write,
39                "file writes require an explicit permit",
40            ),
41            (
42                CanonicalToolSideEffectClass::Admin,
43                "shell execution requires an explicit permit",
44            ),
45            (
46                CanonicalToolSideEffectClass::Analysis,
47                "network access requires an explicit permit",
48            ),
49        ]
50        .into_iter()
51        .map(|(risk_class, reason)| RiskDisclosureV1 {
52            risk_class,
53            granted_by_default: false,
54            permit_required: true,
55            reason: reason.into(),
56        })
57        .collect(),
58        enabled_tool_bundles: vec![
59            "repo-read".into(),
60            "repo-list".into(),
61            "file-stat".into(),
62            "repo-search".into(),
63            "patch-propose".into(),
64            "patch-apply".into(),
65            "run-checks".into(),
66        ],
67        disabled_tool_bundles: vec![
68            "shell-auto".into(),
69            "network-auto".into(),
70            "file-write-auto".into(),
71            "dangerous-auto-approval".into(),
72        ],
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn coding_profile_does_not_auto_grant_dangerous_capabilities() {
82        let plan = coding_agent_plan("agent");
83        assert!(!plan.dangerous_auto_approval);
84        assert!(plan
85            .risk_disclosures
86            .iter()
87            .all(|risk| !risk.granted_by_default && risk.permit_required));
88        assert!(plan.validate().is_ok());
89        let status = ProfileCodingStatus::default();
90        assert!(status.enabled);
91        assert!(status.note.contains(SUPPORT_TIER));
92        assert!(status.note.contains("explicit permits"));
93    }
94}