use std::process::ExitCode;
#[derive(Debug, Clone, Copy)]
pub(crate) struct TrackingIssue {
pub number: u32,
pub label: &'static str,
}
impl TrackingIssue {
pub(crate) fn url(self) -> String {
format!(
"https://github.com/astrid-runtime/astrid/issues/{}",
self.number
)
}
}
pub(crate) fn deferred(feature: &str, issues: &[TrackingIssue]) -> ExitCode {
eprintln!("astrid: {feature} is not available in this release.");
if issues.len() == 1 {
let issue = issues[0];
eprintln!(
" Tracking issue #{} ({}) — see {}",
issue.number,
issue.label,
issue.url()
);
} else {
eprintln!(" Tracking issues:");
for issue in issues {
eprintln!(" #{} ({}) — {}", issue.number, issue.label, issue.url());
}
}
ExitCode::from(2)
}
pub(crate) const ISSUE_DELEGATION: TrackingIssue = TrackingIssue {
number: 656,
label: "sub-agent delegation, capability vouchers, OS-level enforcement",
};
pub(crate) const ISSUE_REMOTE_AUTH: TrackingIssue = TrackingIssue {
number: 658,
label: "remote CLI auth + A2A endpoints",
};
pub(crate) const ISSUE_AUDIT: TrackingIssue = TrackingIssue {
number: 675,
label: "Layer 7 audit log routing",
};
pub(crate) const ISSUE_BUDGET: TrackingIssue = TrackingIssue {
number: 653,
label: "kernel-side budget admin IPC",
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn url_matches_template() {
assert_eq!(
ISSUE_DELEGATION.url(),
"https://github.com/astrid-runtime/astrid/issues/656"
);
}
#[test]
fn deferred_returns_exit_code_two() {
let code = deferred("test", &[ISSUE_DELEGATION]);
let s = format!("{code:?}");
assert!(s.contains('2'), "expected exit code 2, got {s}");
}
}