Skip to content

Develop - #12

Merged
berdanakyurek merged 25 commits into
mainfrom
develop
Mar 15, 2026
Merged

berdanakyurek merged 25 commits into
mainfrom
develop

Conversation

@berdanakyurek

Copy link
Copy Markdown
Owner

No description provided.

berdanakyurek and others added 25 commits March 15, 2026 19:09
sync: merge main into claude-developer-1
Implements entropy-based automatic redaction as a complement to pattern-based
redaction. High-entropy tokens (API keys, tokens, random secrets) are detected
statistically and replaced with [REDACTED] before sending commands to LLM providers.

- internal/redact/entropy.go: Entropy() function + EntropyRedactor struct
- internal/redact/entropy_test.go: tests for entropy calc and redaction behavior
- internal/config/config.go: per-provider entropy_redaction_enabled field,
  global entropy_threshold/entropy_min_length config, UpdateProviderEntropyRedaction()
- internal/llm/multi.go: entropy redactor applied per-provider in Query()
- redact_cmd.go: guard-sh redact entropy on/off subcommand
- main.go: entropy redactor init, entropy state in status output
- help.go: entropy redact commands documented
- config.default.yaml: entropy_threshold (4.5) and entropy_min_length (20) defaults

Closes #10

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Restructures entropy-based redaction config to match the per-provider
nested format specified in issue #10:

  providers:
    claude:
      redact_entropy:
        enabled: true
        threshold: 4.5
        min_length: 20

- EntropyConfig struct nested under ProviderConfig.RedactEntropy
- Removed flat global entropy_threshold/entropy_min_length from Config
- Per-provider EntropyRedactor instances (each with its own threshold/min_length)
- UpdateProviderEntropyRedaction creates/updates nested redact_entropy block
- Multi uses map[string]*EntropyRedactor instead of shared redactor + enabled map
- Status shows threshold and min_length when entropy is on

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adopts the config format requested in PR #11 review comment:

  redaction:                     # global (mandatory)
    pattern_based:
      enabled: true
      patterns: [...]
    shannon_entropy_based:
      enabled: false
      threshold: 4.5
      min_length: 20

  providers:
    claude:
      redaction:                 # optional per-provider override
        shannon_entropy_based:
          enabled: true
          threshold: 4.0
          min_length: 16

Changes:
- New PatternRedactionConfig, EntropyRedactionConfig, RedactionConfig structs
- Config.Redaction replaces flat RedactPatterns field
- ProviderConfig.Redaction replaces PatternBasedRedactionEnabled + RedactEntropy
- EffectivePatternRedaction/EffectiveEntropyRedaction merge global + per-provider
- Multi uses patternRedactors map (per-provider) instead of shared redactor
- UpdateProviderPatternRedaction/UpdateProviderEntropyRedaction write nested YAML
- README.org redaction section fully rewritten
- config.default.yaml updated to new format

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
install.sh was checking for the exact source path, so running it from
a different directory would always add a new entry. Now it detects any
existing guard-sh integration in the rc file and skips if found. Also
copies the shell script to the config dir so the sourced path is stable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Debug output now shows pattern/entropy on|off for every provider,
even when no redaction occurs. Redacted command is shown beneath
the provider line when the command was modified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each provider now shows the command state after pattern redaction
and after entropy redaction separately, with "unchanged" when the
stage produced no modifications.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat: Shannon entropy-based redaction
install.sh was unconditionally overwriting ~/.config/guard-sh/prompt.txt
on every run. Now it skips the copy if the file already exists, matching
the existing behavior for config.yaml.

Closes #14

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…erwrite

fix: preserve custom prompt.txt on reinstall
Cache is moved from guard.Guard into llm.Multi. Each provider now
has its own cache entry keyed as "providerName:command". This ensures:
- Provider 1 failing and Provider 2 answering does not cause Provider 1
  to be skipped on the next run.
- Reordering or removing a provider does not serve stale responses.

Closes #13

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When send_working_directory is true (default), guard-sh now sends:

  Working directory: /etc/nginx
  Command: chmod 777 nginx.conf

to the LLM instead of the bare command. The cache key includes the
working directory so identical commands in different directories are
evaluated independently. Set send_working_directory: false in config
to revert to command-only behaviour.

Closes #16

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two edge cases were untested and broken:

1. Multiline commands — the widget was firing on the first line before
   the full command was assembled. Now checks $CONTEXT: if it is 'cont'
   (zsh waiting for more input due to open quotes, backslash, braces,
   if/for/while bodies etc.), the Enter is passed through unchanged.
   guard-sh intercepts only when $CONTEXT is 'start' (complete input).

2. History expansion — !! / !$ / !cmd tokens were passed raw to
   guard-sh, so it evaluated a different command than what would
   actually run. Now calls `zle .expand-history` before reading
   $BUFFER, so the expanded form is checked.

Closes #15

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cases

fix: handle multiline commands and history expansion in zsh integration
…aware-cache

feat: per-provider cache keys to prevent cross-provider cache hits
- Add shell/guard.fish with full fish integration (bind \n/\r, commandline widget, guard-sh on/off/--global)
- Embed guard.fish in binary via //go:embed
- Update setup.go to write guard.fish and handle fish RC file ($XDG_CONFIG_HOME/fish/config.fish)
- Update install.sh with fish case
- Add TestSetup_FreshInstall_Fish; update UnsupportedShell test to use tcsh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- status command now shows work dir on/off
- README.org: add send_working_directory to config example and add
  dedicated Working directory context section with usage and example
- CLAUDE.md: update request flow, shell integration, config sections
- guard_test.go: add TestCheck_QuerySentToLLM and TestCheck_WhitelistUsesRawCmd

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- healthcheck now checks fish RC file (~/.config/fish/config.fish)
- README.org: add fish to requirements, install descriptions, shell
  support table, healthcheck example, and setup description
- CLAUDE.md: update project description, request flow, and shell
  integration section to include fish

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gration

feat: add fish shell integration
- Remove cache from guard.go (moved to llm.Multi in #13)
- Update guard_test.go: use new New() signature (no cacheMaxSize),
  keep rawCmd/query Check() signature, drop cache tests moved to multi

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…irectory

feat: include working directory in LLM evaluation and cache key
@berdanakyurek
berdanakyurek merged commit 75897b7 into main Mar 15, 2026
1 check passed
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