Repository navigation
fix(security): keep UUIDs intact through Sanitizer phone redaction - #54
Merged
Merged
Conversation
TaskFailure#initialize runs message and context through Security::Sanitizer. The loose phone pattern matched any UUID whose 2nd and 3rd groups are all digits (~4% of SecureRandom.uuid values), turning e.g. 73fb9a6e-9973-4748-87aa-… into 73fb9a6e-[REDACTED_PHONE]-87aa-… and corrupting dependency_id / task ids. This is the random red on the Ruby 3.2.4 CI job for codenamev#40, codenamev#50, codenamev#51 and codenamev#53 (plan_orchestrator_spec 'skips transitively through the graph'). Mask UUID spans with placeholders before applying PII patterns and restore them after; add a regression spec with a digit-heavy UUID. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Collaborator
Author
|
CI evidence from the deps loop (2026-10-13): this flake is no longer a 10% thing, it is red on every run since #34 added the transitive-skip spec.
Each of those specs now mints several UUIDs per example, so the odds of at least one carrying a phone-shaped run went from ~10% per UUID to roughly a coin flip per run. Nothing in #27 or #29 touches the orchestrator; this PR is what turns them green. |
This was referenced Oct 15, 2026
codenamev
approved these changes
Oct 30, 2026
This was referenced Oct 30, 2026
minerva-sky
added a commit
that referenced
this pull request
Oct 31, 2026
…ile (#42) (#83) * deps: raise required_ruby_version to >= 3.2, test a real Ruby matrix (#15) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: add benchmark gem (bundled gem since Ruby 4.0; spec/performance requires it) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Bound the six unconstrained runtime dependencies; lock ruby-openai 8.3.0 ruby-openai gets a range (>= 7.1, < 9) because 7.x and 8.x both pass the suite and a pessimistic ~> 7.1 would strand consumers already resolving 8.x. dry-schema, zeitwerk, ostruct, logger and cgi get ~> at their locked minors. Adding constraints where none existed is semver-visible, so this should ship as a minor bump (CHANGELOG under Unreleased). Closes #16. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * deps: refresh the dev lockfile within its existing constraints `bundle update` honouring every cap already in the Gemfile moves 51 gems: json 2.7 -> 3.1, zeitwerk 2.6 -> 2.8, dry-schema 1.13 -> 1.16 (dry-core 1.0 -> 1.2, dry-types 1.7 -> 1.9), async 2.24 -> 2.37 (the Gemfile cap the lock never reached), thor 1.3 -> 1.5, standard 1.32 -> 1.57 (rubocop 1.91), rspec 3.13.0 -> 3.13.2, webmock 3.23 -> 3.34. These are the versions a fresh `gem install agentic` already resolves to; CI was testing the old numbers. The refresh drops the orphan base64 entry that vcr 6.3 pulled in, which is the only thing that let authentication_system.rb's dead `require "base64"` load on Ruby >= 3.4 (base64 is a bundled gem there). The require goes; the file never calls Base64. Suite on the refreshed lock (Ruby 4.0.2): 1391 examples, the two pre-existing flakes only (plan_orchestrator_spec:243 UUID redaction, #54; event_dispatcher_integration_spec:291 wall clock, #36). standardrb 1.57 reports no offences. Closes #64. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * deps: cap parallel and simplecov for the Ruby 3.2.4 CI floor The refresh resolved on Ruby 4.0.2 and let parallel 2.3.0 (via rubocop 1.91) and simplecov 1.3.2 into the lock; both declare required_ruby_version >= 3.3, so CI's frozen install on 3.2.4 would fail before a spec ran. Same cap pattern as async/console/dry-configurable/ io-event: parallel < 2 (1.28.0, floor 2.7), simplecov < 1.3 (1.2.0, floor 3.2). Every locked spec now satisfies 3.2.4. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * deps: move the Ruby 3.2 caps out of the Gemfile into a floor-leg gemfile (#42) The shared Gemfile caps pinned every CI leg to the 3.2-era dependency set, so the 3.3/3.4/latest legs never exercised the async a consumer on a maintained Ruby installs. The 3.2 leg now loads gemfiles/ruby-3.2.gemfile, which gets its own lockfile resolved on 3.2; Bundler's required_ruby_version check selects the same versions the caps did, so the file carries none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * deps: commit the 3.2 leg's lockfile and let Dependabot move it Panel revision: an unlocked floor leg re-resolved against live rubygems on every run, so an upstream release could turn it red with no commit and no Dependabot PR to bisect against. The floor gemfile moves to gemfiles/ruby-3.2/Gemfile (Dependabot only discovers files named Gemfile), its lockfile is committed, a ruby '< 3.3' line keeps Dependabot inside 3.2, and dependabot.yml gains a bundler entry for the directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: audit the Ruby 3.2 lockfile; document regenerating it Panel notes on the revision: audit.yml's paths filter and check covered only the root Gemfile.lock, and a root Gemfile change now needs the floor lockfile re-resolved on 3.2 or that leg fails its frozen install. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: Valentino Stoll <v@codenamev.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The Ruby 3.2.4 CI job goes red at random on #40, #50, #51 and #53 — always the same example,
plan_orchestrator_spec"skips transitively through the graph", with output like:Not a Ruby/Linux/ordering issue — the mask is produced inside the object under test.
TaskFailure#initializesanitizesmessageandcontextthroughSecurity::Sanitizer, whose second phone regex matches any UUID whose 2nd + 3rd groups are all digits (9973-4748). About 4% ofSecureRandom.uuidvalues qualify, so every spec that asserts on adependency_idor an id inside a failure message flakes at that rate. Local runs just got lucky.Fix
Sanitizer#sanitize_stringmasks UUID spans with placeholders before the PII patterns run and restores them afterwards (PROTECTED_SPANS). Fixes message and context together.Probe: 2000 random UUIDs through the sanitizer → 0 mangled (was ~4%).
Verified under ruby 3.2.4,
--order defined: sanitizer + task_failure + plan_orchestrator specs, 57 examples, 0 failures; standardrb clean.Once merged, rebasing #40/#50/#51/#53 (or just re-running their CI after main moves) should turn the 3.2.4 job green.
🤖 Generated with Claude Code
Closes #41.