Skip to content
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
24 changes: 22 additions & 2 deletions .github/workflows/nightly-deep-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ name: Nightly Deep CI
# - Windows compile matrix
# - benchmark compilation
#
# The Reborn binary suites are reused the same way:
# - .github/workflows/reborn-tests.yml: per-crate tests across the Reborn
# crate families plus the partitioned root parity tests (with
# event_name == schedule, scope detection short-circuits to full scope)
# - .github/workflows/reborn-e2e.yml: deterministic Rust contract gate
# (architecture/runtimes/substrates) plus gateway and WebUI v2 smoke
# (workflow_call bypasses the PR path filters, so the full gate runs)
#
# Docker is intentionally excluded here because QA/release Docker images are
# owned by the separate Docker pipeline and need release-team alignment.
# Full browser E2E is scheduled separately by .github/workflows/e2e.yml.
Expand All @@ -36,6 +44,18 @@ jobs:
ref: ${{ github.sha }}
include_docker: false

reborn-tests:
name: Reborn Tests
uses: ./.github/workflows/reborn-tests.yml
with:
ref: ${{ github.sha }}

reborn-e2e:
name: Reborn E2E
uses: ./.github/workflows/reborn-e2e.yml
with:
ref: ${{ github.sha }}

nightly-alert:
name: Nightly Deep CI Alert
runs-on: ubuntu-latest
Expand All @@ -44,7 +64,7 @@ jobs:
actions: read
contents: read
issues: write
needs: [deterministic-deep-tests]
needs: [deterministic-deep-tests, reborn-tests, reborn-e2e]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
Expand All @@ -55,5 +75,5 @@ jobs:
REPO: ${{ github.repository }}
ALERT_WORKFLOW_NAME: Nightly Deep CI
ALERT_ISSUE_TITLE: Nightly Deep CI failed
ALERT_RESULT: ${{ needs.deterministic-deep-tests.result }}
ALERT_RESULT: ${{ (needs.deterministic-deep-tests.result == 'success' && needs.reborn-tests.result == 'success' && needs.reborn-e2e.result == 'success') && 'success' || 'failure' }}
run: .github/scripts/nightly-alert-issue.sh
227 changes: 0 additions & 227 deletions .github/workflows/reborn-integration.yml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,11 @@ fn google_callback_state_round_trips_through_validated_encoded_state() {

#[test]
fn google_callback_state_rejects_unapproved_requested_scopes() {
let invalid_scope = ProviderScope::new("https://www.googleapis.com/auth/drive").unwrap();
// `gmail.insert` is a real, sensitive Gmail scope deliberately kept out of
// the approved GSuite set (`is_allowed_google_scope`). The approved set grew
// to include the Drive/Docs/Sheets/Slides scopes in #4326, so this guards the
// boundary with a scope that is still outside it.
let invalid_scope = ProviderScope::new("https://www.googleapis.com/auth/gmail.insert").unwrap();

assert_invalid_request(GoogleOAuthCallbackState::new(
AuthFlowId::new(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,19 @@ mod tests {

#[test]
fn provider_tool_call_validation_rejects_sensitive_metadata() {
// Arguments carrying a real secret-like token are rejected by the
// entropy-based leak scan, which is the canonical guard after #5001
// dropped the crude bare-word substring markers.
let mut call = provider_tool_call();
let api_key = format!("sk-proj-{}", "a".repeat(24));
call.arguments = serde_json::json!({"password": api_key});
assert!(validate_provider_tool_call(&call).is_err());

// The same leak scan runs over model-emitted reasoning, so a leaked
// secret-like token there is rejected even though bare words like
// "traceback" are now intentionally allowed (#5001, PinchBench bucket D).
let mut call = provider_tool_call();
call.reasoning = Some("provider error included traceback".to_string());
call.reasoning = Some(format!("provider error leaked sk-proj-{}", "b".repeat(24)));
assert!(validate_provider_tool_call(&call).is_err());
}

Expand Down
9 changes: 8 additions & 1 deletion crates/ironclaw_threads/src/tool_result_reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,13 +880,20 @@ mod tests {

#[test]
fn provider_reference_validation_rejects_sensitive_arguments_and_text() {
// Arguments carrying a real secret-like token are rejected by the
// entropy-based leak scan, which is the canonical guard after #5001
// dropped the crude bare-word substring markers.
let mut envelope = provider_reference();
let api_key = format!("sk-proj-{}", "a".repeat(24));
envelope.arguments = serde_json::json!({"api_key": api_key});
assert!(envelope.validate().is_err());

// Provider reasoning text flows through the same leak scan, so a leaked
// secret-like token there is rejected even though bare words like
// "stack trace" are now intentionally allowed (#5001, PinchBench bucket D).
let mut envelope = provider_reference();
envelope.response_reasoning = Some("raw provider error included a stack trace".to_string());
envelope.response_reasoning =
Some(format!("provider error leaked sk-proj-{}", "b".repeat(24)));
assert!(envelope.validate().is_err());
}

Expand Down
2 changes: 1 addition & 1 deletion scripts/ci/classify-test-scope.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ is_shared_test_path() {
scripts/ci/classify-test-scope.sh|scripts/ci/test-classify-test-scope.sh|scripts/ci/package-feature-flags.sh)
return 0
;;
.github/workflows/test.yml|.github/workflows/reborn-tests.yml|.github/workflows/reborn-integration.yml|.github/workflows/reborn-e2e.yml|.github/workflows/nightly-deep-ci.yml)
.github/workflows/test.yml|.github/workflows/reborn-tests.yml|.github/workflows/reborn-e2e.yml|.github/workflows/nightly-deep-ci.yml)
return 0
;;
crates/ironclaw_common/*|crates/ironclaw_host_api/*|crates/ironclaw_host_runtime/*|crates/ironclaw_loop_support/*)
Expand Down
Loading