Skip to content

Threshold sync semantics: enforce cloud_only fail-closed, clear override safely, and apply cloud project settings #11

@miraniy98

Description

@miraniy98

Problem

Threshold sync implementation is close, but there are semantic gaps that can cause behavior to diverge from configured policy:

  1. cloud_only + fail_open=false is currently bypassed by broad exception fallback in scan flow.
  2. Per-scan thread-local threshold override is not cleared if detector throws, risking stale override leakage.
  3. Cloud project_settings returned by resolve endpoint are fetched but not applied in SDK (with local-explicit-wins semantics).

Expected behavior

  • cloud_only with fail_open=false must fail closed and raise ThresholdUnavailableError.
  • Threshold override must always be cleared, including failure paths.
  • SDK should apply cloud project_settings (confidence_threshold, cleaning_method, on_detect) only when not explicitly set locally.
  • Applying cloud cleaning method should invalidate/rebuild cleaner + detector.
  • Resolution fetch should not be duplicated when settings + mode are both needed.

Proposed changes

  • Narrow exception handling in AgentShield._scan_single():
    • re-raise ThresholdUnavailableError
    • only soft-fallback on transient/non-policy errors
  • Wrap detect call in try/finally and always clear threshold override.
  • Add single-fetch flow:
    • fetch cloud_resolution once
    • apply cloud settings from project_settings block
    • pass same cloud_resolution into resolve_with_mode(...)
  • Extend ThresholdManager.resolve_with_mode(...) to accept optional cloud_resolution.
  • Remove unrelated .gitignore change (docs/) from threshold-sync scope.

Acceptance criteria

  • cloud_only + fail_open=false raises and does not silently fall back.
  • No override leakage across scans when detect errors occur.
  • Cloud settings are applied only when local explicit values are absent.
  • Cleaner/detector rebuild when cloud cleaning method is applied.
  • All tests pass.

Tests to add

  • tests/test_shield.py
    • fail-closed test for cloud_only
    • override-clear-on-exception test
    • cloud settings applied/not-applied cases
    • cleaner/detector invalidation on cloud cleaning method
  • tests/test_threshold.py
    • resolve_with_mode(..., cloud_resolution=...) no second fetch

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions