Skip to content

feat(guard,secrets): port the June 2026 detector series - #9

Merged
random1st merged 1 commit into
mainfrom
feat/port-june-detectors
Aug 9, 2026
Merged

feat(guard,secrets): port the June 2026 detector series#9
random1st merged 1 commit into
mainfrom
feat/port-june-detectors

Conversation

@random1st

Copy link
Copy Markdown
Owner

Six modules written against diana-guard / diana-secrets in June 2026 that never landed anywhere. Diana's branch holding them was deleted (tagged archive/secguard-detectors-20260607 in the Diana repo); the guard layer lives here now, so this is the port rather than a revival.

Module What it does Lines
guard::autostash git stash -u before a high-blast command in a dirty tree 503
guard::deobfuscate AST-level base64 / eval / obfuscated-payload unwrapping 811
guard::findings persisted verdict envelope, content-fingerprinted 332
guard::injection indirect prompt-injection detection over untrusted text 568
guard::lockdown network-egress denial — curl, wget, nc, ssh, scp, gh api 462
secrets::verifier live provider-side token verification 856

Wiring worth naming

Lockdown runs as phase 0 of check_detailed, before the policy allowlist. That order is the point: a user-defined safe_command_prefixes entry must not be able to open a hole in a mode whose whole purpose is that nothing leaves.

verification is off by default. The HTTP stack is a large dependency and a network call from inside a sync hook is a deliberate choice, never an accident of building the crate.

prompt-injection-ml is declared because the injection module gates an ML path behind it; the deterministic rules run without it.

Adapted, not copied

  • VerdictDetail::new gained a config parameter after June — the lockdown call site passes it.
  • RuleId::LockdownEgress added with its damage mapping (D::new(3, 0): blocks exfiltration, and the target being remote means recovery is not local).
  • AutostashConfig / LockdownConfig / InjectionConfig spliced into the existing GuardConfig rather than overwriting a config that has evolved since.
  • eprintln!log::warn!.
  • Two inherent default() constructors became at_default_path(). Both do I/O, and an inherent default shadowing Default::default at the call site means a reader cannot tell which one they are getting.

Verification

cargo test --workspace                        # 594 passed, 0 failed (13 suites)
cargo clippy --workspace --all-targets -- -D warnings   # clean
cargo check -p secguard-secrets --features verification # builds
cargo fmt --all -- --check                    # clean

Defaults are unchanged: lockdown.enabled = false, verification off, prompt-injection-ml off. autostash.enabled = true at blast ≥ 3 — the one behaviour change worth a second look before merge.

Six modules that were written against diana-guard and diana-secrets in
June and never landed anywhere. Diana's copy was deleted along with the
branch that held them; this repository is where the guard layer lives now,
so this is the port rather than a revival.

  autostash     git stash -u before a high-blast command in a dirty tree
  deobfuscate   AST-level base64 / eval / obfuscated-payload unwrapping
  findings      persisted verdict envelope, content-fingerprinted
  injection     indirect prompt-injection detection over untrusted text
  lockdown      network-egress denial: curl, wget, nc, ssh, scp, gh api
  verifier      live provider-side token verification, behind a feature

Wiring worth naming:

Lockdown runs as phase 0 of `check_detailed`, before the policy allowlist.
That order is the point — a user-defined safe_command_prefixes entry must
not be able to open a hole in a mode whose whole purpose is that nothing
leaves.

`verification` is off by default. The HTTP stack is a large dependency and
a network call from inside a sync hook is a deliberate choice, never an
accident of building the crate.

`prompt-injection-ml` is declared because the injection module gates an ML
path behind it; the deterministic rules run without it.

Two inherent `default()` constructors became `at_default_path()`. Both do
I/O, and an inherent `default` shadowing `Default::default` at the call
site means a reader cannot tell which one they are getting.

Adapted from the original: VerdictDetail::new now takes the config
(post-June signature change), RuleId::LockdownEgress and the three config
sections were added rather than copied wholesale, and eprintln became
log::warn.

594 tests pass, clippy --all-targets clean.
@random1st
random1st merged commit d45bbb5 into main Aug 9, 2026
4 checks passed
@random1st
random1st deleted the feat/port-june-detectors branch August 9, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant