Skip to content
This repository was archived by the owner on Sep 23, 2026. It is now read-only.
Merged
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
41 changes: 39 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,53 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
- name: Checkout AIEN Protocols Dependency
uses: actions/checkout@v4
with:
repository: aien-dev/aien-protocols
path: aien-protocols

- name: Setup Sibling Dependencies
run: |
mkdir -p ../aien-protocols
cp -r aien-protocols/* ../aien-protocols/

- name: Install Stable Rust Toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Verify Code Formatting
run: cargo fmt --all -- --check

- name: Cargo Check
run: cargo check --all-targets

- name: Cargo Clippy Invariant
run: cargo clippy --all-targets -- -D warnings

- name: Run Tests
run: cargo test --verbose
run: cargo test --verbose -- --test-threads=1

- name: Enforce Zero Disk Secrets Invariant
run: |
echo "Auditing repository for prohibited plaintext secret files..."
if find . -maxdepth 4 -name ".env*" -not -path "*/.git/*" -not -path "*/target/*" | grep -q .; then
echo "::error::Prohibited plaintext .env file found. Use an approved AIEN SecretProvider."
exit 1
fi
echo "Zero plaintext .env files verified."

- name: Enforce Sovereign Voice and Anti-Slop Invariant
run: |
echo "Auditing repository for em dashes, en dashes, and formulaic tropes..."
BAD_CHARS=$(grep -rnE --exclude-dir=target --exclude-dir=.git --exclude-dir=aien-protocols --exclude="*.rs" --exclude="*.json" --exclude="*.safetensors" "—|–" src/ tests/ README.md || true)
if [ -n "$BAD_CHARS" ]; then
echo "::error::Em dashes or en dashes detected:"
echo "$BAD_CHARS"
exit 1
fi
echo "Sovereign voice compliance verified."

- name: Build Release Binary
run: cargo build --release
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ Cargo.lock
*.tar.gz
*.sha256
.crumb.local
aien-protocols/
52 changes: 44 additions & 8 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ author: "Drake Stapleton <drake.aien@proton.me> & AIEN <aien.atlas@proton.me>"

inputs:
command:
description: "Inquisitor command: review, triage-issue, evaluate, audit, or doctor"
description: "Inquisitor command: review, triage-issue, interview, audit, evaluate, or doctor"
required: true
default: "review"
diff:
Expand Down Expand Up @@ -38,10 +38,46 @@ runs:
- name: Run Sovereign Inquisitor
shell: bash
run: |
spark-inquisitor "${{ inputs.command }}" \
--diff "${{ inputs.diff }}" \
--author "${{ inputs.author }}" \
--pr "${{ inputs.pr }}" \
--title "${{ inputs.title }}" \
--output "${{ inputs.output-comment }}" \
--output-labels "${{ inputs.output-labels }}"
case "${{ inputs.command }}" in
doctor)
spark-inquisitor doctor
;;
review)
spark-inquisitor review \
--diff "${{ inputs.diff }}" \
--author "${{ inputs.author }}" \
--pr "${{ inputs.pr }}" \
--title "${{ inputs.title }}" \
--output "${{ inputs.output-comment }}" \
--output-labels "${{ inputs.output-labels }}"
;;
triage-issue)
spark-inquisitor triage-issue \
--author "${{ inputs.author }}" \
--issue "${{ inputs.pr }}" \
--title "${{ inputs.title }}" \
--body "${{ inputs.diff }}" \
--output-comment "${{ inputs.output-comment }}" \
--output-labels "${{ inputs.output-labels }}"
;;
interview)
spark-inquisitor interview \
--author "${{ inputs.author }}" \
--pr "${{ inputs.pr }}" \
--title "${{ inputs.title }}"
;;
audit)
spark-inquisitor audit \
--diff "${{ inputs.diff }}"
;;
evaluate)
spark-inquisitor evaluate \
--testimony "${{ inputs.diff }}" \
--author "${{ inputs.author }}" \
--output-comment "${{ inputs.output-comment }}" \
--output-labels "${{ inputs.output-labels }}"
;;
*)
spark-inquisitor "${{ inputs.command }}"
;;
esac
41 changes: 21 additions & 20 deletions src/audit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,26 +142,27 @@ impl DiffAuditor {
}

// In non-markdown source code, also flag raw telemetry calls
if !current_file.ends_with(".md") && line.starts_with('+') && !line.starts_with("+++") {
if lower.contains("telemetry")
&& !lower.contains("gpu-telemetry")
&& !lower.contains("zero telemetry")
&& !lower.contains("zero-telemetry")
&& !lower.contains("no-telemetry")
&& !lower.contains("no telemetry")
&& !lower.contains("anti-telemetry")
&& !lower.contains("block telemetry")
&& !lower.contains("telemetryforbidden")
&& !lower.contains("networkpurpose::telemetry")
&& !lower.contains("forbid")
&& !lower.contains("reject")
{
violations.push(format!(
"Telemetry indicator detected in source line: {}",
line.trim()
));
telemetry_detected = true;
}
if !current_file.ends_with(".md")
&& line.starts_with('+')
&& !line.starts_with("+++")
&& lower.contains("telemetry")
&& !lower.contains("gpu-telemetry")
&& !lower.contains("zero telemetry")
&& !lower.contains("zero-telemetry")
&& !lower.contains("no-telemetry")
&& !lower.contains("no telemetry")
&& !lower.contains("anti-telemetry")
&& !lower.contains("block telemetry")
&& !lower.contains("telemetryforbidden")
&& !lower.contains("networkpurpose::telemetry")
&& !lower.contains("forbid")
&& !lower.contains("reject")
{
violations.push(format!(
"Telemetry indicator detected in source line: {}",
line.trim()
));
telemetry_detected = true;
}

// Constitutional unslop and secret invariant scanning on added lines
Expand Down
19 changes: 10 additions & 9 deletions src/constitution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ impl ConstitutionalChecker {
// AWS Access Key ID: AKIA followed by 16 alphanumeric uppercase
let aws_regex = AWS_REGEX.get_or_init(|| Regex::new(r"\bAKIA[0-9A-Z]{16}\b").unwrap());
if aws_regex.is_match(line) {
violations.push(ViolationKind::Secret(format!(
"Plaintext AWS Access Key detected in line: [REDACTED_AWS_KEY]"
)));
violations.push(ViolationKind::Secret(
"Plaintext AWS Access Key detected in line: [REDACTED_AWS_KEY]".to_string(),
));
}

// GitHub Personal Access Tokens (ghp_... or github_pat_...)
Expand All @@ -58,19 +58,20 @@ impl ConstitutionalChecker {
let github_fine_pat_regex = GITHUB_FINE_PAT_REGEX
.get_or_init(|| Regex::new(r"\bgithub_pat_[A-Za-z0-9_]{50,}\b").unwrap());
if github_pat_regex.is_match(line) || github_fine_pat_regex.is_match(line) {
violations.push(ViolationKind::Secret(format!(
violations.push(ViolationKind::Secret(
"Plaintext GitHub Personal Access Token detected in line: [REDACTED_GH_TOKEN]"
)));
.to_string(),
));
}

// Private Keys
let priv_key_regex = PRIV_KEY_REGEX.get_or_init(|| {
Regex::new(r"-----BEGIN (?:[A-Z0-9 ]+)?PRIVATE KEY-----|BEGIN RSA PRIVATE KEY").unwrap()
});
if priv_key_regex.is_match(line) {
violations.push(ViolationKind::Secret(format!(
"Plaintext Private Key header detected in line: [REDACTED_PRIVATE_KEY]"
)));
violations.push(ViolationKind::Secret(
"Plaintext Private Key header detected in line: [REDACTED_PRIVATE_KEY]".to_string(),
));
}

// 3. Banned AI Buzzwords & Tropes
Expand Down Expand Up @@ -199,7 +200,7 @@ impl ConstitutionalChecker {

pub fn is_env_file(path: &str) -> bool {
let clean_path = path.trim().trim_matches('"').trim_matches('\'');
let filename = clean_path.split('/').last().unwrap_or(clean_path);
let filename = clean_path.split('/').next_back().unwrap_or(clean_path);
filename == ".env" || filename.starts_with(".env.")
}
}
5 changes: 1 addition & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,7 @@ fn main() {
output_comment,
output_labels,
} => {
let body_content = match fs::read_to_string(&body) {
Ok(c) => c,
Err(_) => String::new(),
};
let body_content = fs::read_to_string(&body).unwrap_or_default();

let result = triage_issue(&author, issue, &title, &body_content);

Expand Down
46 changes: 35 additions & 11 deletions tests/protocol_integration.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use aien_evaluation_protocol::{
VerifierSigner,
CanaryRollbackHarness, EvaluationPlan, Evaluator, EvaluatorDescriptor,
EvaluatorStatus, SoftwareP256Signer, Verdict, VerifierIdentity,
CanaryRollbackHarness, EvaluationPlan, Evaluator, EvaluatorDescriptor, EvaluatorStatus,
SoftwareP256Signer, Verdict, VerifierIdentity, VerifierSigner,
};
use aien_protocol_types::{ArtifactRef, Digest32, EvaluationId, Timestamp};
use p256::ecdsa::SigningKey;
Expand Down Expand Up @@ -57,7 +56,10 @@ diff --git a/src/lib.rs b/src/lib.rs
let plan = create_test_plan();
let subject = plan.subject.clone();

let outcome = eval.evaluate(&plan, &subject).await.expect("evaluation error");
let outcome = eval
.evaluate(&plan, &subject)
.await
.expect("evaluation error");
assert_eq!(outcome.status, EvaluatorStatus::Passed);
assert!(outcome.findings.is_empty());
assert_ne!(outcome.execution_digest, Digest32::ZERO);
Expand All @@ -81,13 +83,26 @@ diff --git a/src/lib.rs b/src/lib.rs
let plan = create_test_plan();
let subject = plan.subject.clone();

let outcome = eval.evaluate(&plan, &subject).await.expect("evaluation error");
let outcome = eval
.evaluate(&plan, &subject)
.await
.expect("evaluation error");
assert_eq!(outcome.status, EvaluatorStatus::Failed);
assert!(!outcome.findings.is_empty());

let rule_ids: Vec<&str> = outcome.findings.iter().map(|f| f.rule_id.as_str()).collect();
assert!(rule_ids.contains(&"CONSTITUTIONAL_TELEMETRY"), "Must catch posthog telemetry");
assert!(rule_ids.contains(&"SOVEREIGN_UNSLOP"), "Must catch em dash and buzzwords");
let rule_ids: Vec<&str> = outcome
.findings
.iter()
.map(|f| f.rule_id.as_str())
.collect();
assert!(
rule_ids.contains(&"CONSTITUTIONAL_TELEMETRY"),
"Must catch posthog telemetry"
);
assert!(
rule_ids.contains(&"SOVEREIGN_UNSLOP"),
"Must catch em dash and buzzwords"
);
}

#[tokio::test]
Expand All @@ -98,12 +113,18 @@ async fn test_inquisitor_constitutional_evaluator() {
let plan = create_test_plan();
let subject = plan.subject.clone();

let outcome_good = eval_good.evaluate(&plan, &subject).await.expect("evaluation error");
let outcome_good = eval_good
.evaluate(&plan, &subject)
.await
.expect("evaluation error");
assert_eq!(outcome_good.status, EvaluatorStatus::Passed);

let bad_testimony = "I decline to affirm the oath and intend to add tracking.";
let eval_bad = InquisitorConstitutionalEvaluator::with_testimony(bad_testimony.to_string());
let outcome_bad = eval_bad.evaluate(&plan, &subject).await.expect("evaluation error");
let outcome_bad = eval_bad
.evaluate(&plan, &subject)
.await
.expect("evaluation error");
assert_eq!(outcome_bad.status, EvaluatorStatus::Failed);
}

Expand Down Expand Up @@ -150,7 +171,10 @@ async fn test_inquisitor_canary_rollback_integration() {
.await
.expect("harness evaluation failed");

assert!(rollback_triggered.load(Ordering::SeqCst), "Rollback must execute on unslop violation");
assert!(
rollback_triggered.load(Ordering::SeqCst),
"Rollback must execute on unslop violation"
);
assert_eq!(receipt.receipt.verdict, Verdict::Fail);

let verifying_key = signer.verifying_key();
Expand Down
Loading