Skip to content

fix(agent): match the Python agent in redaction, transport and flush semantics - #58

Merged
rennf93 merged 1 commit into
masterfrom
fix/parity-gaps
Oct 15, 2026
Merged

rennf93 merged 1 commit into
masterfrom
fix/parity-gaps

Conversation

@rennf93

@rennf93 rennf93 commented Oct 15, 2026

Copy link
Copy Markdown
Member

Closes #57

I audited guard-agent-rs against the Python agent (guard-agent master) and fixed every divergence I could reproduce. Each change has a test that failed on master first.

Redaction: Redactor now follows sanitize_headers. It recurses to depth 10 and redacts anything deeper wholesale, parses JSON-looking string values, sanitizes inside them and re-dumps them with Python's json.dumps formatting, redacts JSON-looking strings over 8192 characters wholesale, and applies the same rules to metric tag values. Strings that Python parses but serde_json cannot (lone surrogate escapes, nesting past the parser limit) are redacted wholesale instead of passing through, and the NaN and Infinity literals are handled. The transport runs a second pass over event metadata and metric tags before serializing, plain and encrypted. The expected values in tests/fixtures/sanitize_vectors.json come from running the reference function on the same inputs. serde_json gets preserve_order so re-dumped strings keep key order like Python.

Transport and flush:

  • An encrypted batch answered with 413 is split and each half is re-encrypted, instead of being dropped with its Redis records.
  • After a 413 split both halves are always sent, and the batch is confirmed only when both were.
  • A dropped permanent rejection counts as sent, resets the flush streak and clears the retry gate.
  • A rejected status push is a failed push.
  • POST success is exactly 200 or 201. An unparseable 200, a 200 with an empty object, 202, 204, 3xx and other unlisted statuses are retried at once without backoff and without a breaker failure. A 200 body that is not an object is accepted, and errors uses Python truthiness. Redirects are no longer followed. GET follows the same status rules.
  • The rules loop starts only when a project id is set.
  • loop_failures.flush resets on every completed loop iteration, as in the reference, instead of counting failed flushes.
  • An encryption key with surrounding whitespace is accepted.
  • Docs: the signing note now says the Python agent also signs the uncompressed body, and AGENTS.md and CLAUDE.md no longer say version 0.1.0.

Existing tests that pinned the old behavior (drop does not count as sent, right half skipped, any 2xx accepted, rules loop without a project id) are updated to the reference behavior. I did not touch CHANGELOG.md because release prep owns it in this repo.

I ran fmt, clippy with -D warnings (default and all features), cargo test and cargo test --all-features -- --include-ignored against Redis, cargo doc with -D warnings, the MSRV 1.92 check and tests, cargo deny, cargo audit and the 100% line coverage gate locally.

@rennf93 rennf93 added bug Confirmed defect area: core Touches the agent lifecycle, config, or models area: transport Touches HTTP transport or payload signing tests Test suite changes labels Oct 15, 2026
@github-actions github-actions Bot added documentation Docs, README, governance files build Workspace files / packaging dependencies Cargo.toml or Cargo.lock changes labels Oct 15, 2026
@rennf93
rennf93 merged commit 36b306f into master Oct 15, 2026
15 checks passed
@rennf93
rennf93 deleted the fix/parity-gaps branch October 15, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: core Touches the agent lifecycle, config, or models area: transport Touches HTTP transport or payload signing bug Confirmed defect build Workspace files / packaging dependencies Cargo.toml or Cargo.lock changes documentation Docs, README, governance files tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(agent): parity gaps against the Python agent in redaction, transport and flush

1 participant