Skip to content

refactor: per-workspace script cleanup and CI path filtering#316

Merged
ioncache merged 7 commits into
mainfrom
feat/ci-script-cleanup
May 27, 2026
Merged

refactor: per-workspace script cleanup and CI path filtering#316
ioncache merged 7 commits into
mainfrom
feat/ci-script-cleanup

Conversation

@ioncache
Copy link
Copy Markdown
Owner

@ioncache ioncache commented May 27, 2026

Summary

  • Renamed root orchestrator scripts to :all suffix (lint:all, format:all, build:all, etc.) so root-scoped work scripts (lint, format, format:check) can use the plain names without recursion
  • Removed duplicate :code / :src script aliases from both packages — each workspace now has one canonical script per action
  • Split monolithic ci.yml into three per-workspace workflows with path filters: ci-root.yml, ci-data-sanitization.yml, ci-data-sanitization-log-providers.yml
  • CI now only runs for the workspace(s) whose files changed; data-sanitization-log-providers also triggers on packages/data-sanitization/** since it has that as a workspace peer dep

Test plan

  • ci-root.yml triggers on this PR (root files changed: package.json, .github/workflows/**)
  • ci-data-sanitization.yml triggers (root package.json in its path filter)
  • ci-data-sanitization-log-providers.yml triggers (root package.json in its path filter)
  • All three workflows pass
  • yarn lint:all, yarn format:check:all, yarn build:all, yarn test:all all pass locally (verified)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Split CI into dedicated workflows per workspace and removed the legacy consolidated CI workflow
    • Added root-only CI for formatting/linting and package-specific CI that runs build/test/coverage
    • Automated coverage badge and report updates on pushes for relevant packages
    • Standardized root and package script names for format/lint/test/build
  • Documentation

    • Added a CI and script cleanup plan documenting the refactor and verification steps
    • Updated package READMEs and CI status badges

Review Change Stack

ioncache and others added 4 commits May 26, 2026 22:55
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…providers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ddf13c7d-741d-4e22-90b0-f7538e6a7734

📥 Commits

Reviewing files that changed from the base of the PR and between fbf234d and 9e51180.

📒 Files selected for processing (5)
  • .github/workflows/ci-data-sanitization-log-providers.yml
  • .github/workflows/ci-data-sanitization.yml
  • .github/workflows/ci-root.yml
  • packages/data-sanitization-log-providers/README.md
  • packages/data-sanitization/README.md
💤 Files with no reviewable changes (1)
  • .github/workflows/ci-root.yml
✅ Files skipped from review due to trivial changes (2)
  • packages/data-sanitization-log-providers/README.md
  • packages/data-sanitization/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/ci-data-sanitization.yml
  • .github/workflows/ci-data-sanitization-log-providers.yml

📝 Walkthrough

Walkthrough

Split the monolithic CI into three targeted workflows (root, data-sanitization, data-sanitization-log-providers), removed the old .github/workflows/ci.yml, and standardized root/package npm scripts (root *:all orchestrators; canonical package lint scripts) while preserving per-package coverage badge/report updates via Gist on Node 24 pushes.

Changes

CI Workflow Refactoring and Script Consolidation

Layer / File(s) Summary
Implementation plan and strategy
docs/superpowers/plans/2026-05-26-ci-and-script-cleanup.md
Comprehensive plan document outlining the refactor, target script naming, file operations (create three workflows, delete ci.yml, update package.json files), verification commands, and YAML validation steps.
Root workspace script consolidation
package.json
Root package.json scripts replaced with canonical *:all orchestrators (e.g., build:all, format:all, lint:ci:all, test:coverage:all) and removed duplicated :src/:code variants.
Package-level script standardization
packages/data-sanitization/package.json, packages/data-sanitization-log-providers/package.json
Standardized lint scripts to lint (oxlint -f default), lint:ci (oxlint -f github), and lint:fix (oxlint --fix) with yarn lint:md chaining; removed legacy :code/:src script variants.
Root-level CI workflow
.github/workflows/ci-root.yml
New workflow triggers on root/.github/doc changes (excluding data-sanitization workflows) and runs yarn format:check and yarn lint:ci on Node 22 with yarn install --immutable.
Data sanitization package CI with coverage tracking
.github/workflows/ci-data-sanitization.yml
Per-package CI for packages/data-sanitization using Node 22/24 matrix: format/lint/build/test:coverage. On Node 24 push, extracts line coverage from Vitest JSON via jq, updates a dynamic badge in a Gist, and runs update-coverage-gist.mjs.
Log providers package CI with coverage tracking
.github/workflows/ci-data-sanitization-log-providers.yml
Per-package CI for packages/data-sanitization-log-providers (also watches packages/data-sanitization/**): Node 22/24 matrix, workspace CI steps, and Node-24 push coverage badge/report updates via Vitest JSON, jq, dynamic-badges-action, and the shared update script.
README updates
packages/data-sanitization-log-providers/README.md, packages/data-sanitization/README.md
Add package header and badges for log-providers README; update data-sanitization CI badge target to new workflow.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped through YAML fields and scripts so fine,

Split one CI into three and trimmed each line.
Root scripts now wear :all like a crown,
Packages tidy, no duplicates found.
Gist badges gleam — a rabbit's tidy sign.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically summarizes the main refactoring changes: script cleanup (renaming to :all suffixes, removing duplicates) and CI path filtering (splitting monolithic workflow into per-workspace workflows).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ci-script-cleanup

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

Coverage Report for packages/data-sanitization

Status Category Percentage Covered / Total
🔵 Lines 100% 234 / 234
🔵 Statements 100% 239 / 239
🔵 Functions 100% 27 / 27
🔵 Branches 100% 170 / 170
File CoverageNo changed files found.
Generated in workflow #3 for commit 9e51180 by the Vitest Coverage Report Action

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci-data-sanitization-log-providers.yml:
- Around line 7-23: The workflow's push and pull_request path filters under the
pull_request job omit shared root lint config files (e.g., .markdownlint.json),
so update the paths arrays in the workflow (the pull_request.paths and the
push.paths entries shown) to include the workspace root lint config filenames
(for example add '.markdownlint.json' and any other shared root config files) so
config-only changes trigger the CI; ensure both the push and pull_request paths
sections are updated consistently.

In @.github/workflows/ci-data-sanitization.yml:
- Around line 6-21: The workflow's push and pull_request path filters (the two
paths arrays in .github/workflows/ci-data-sanitization.yml) omit shared root
lint/config files so config-only changes can skip CI; update both 'paths' lists
to include the workspace's shared lint/config files (for example add entries for
.markdownlint.json and any other root lint configs used by the workspace) so
changes to those files trigger the data-sanitization workflow.

In @.github/workflows/ci-root.yml:
- Around line 38-40: Remove the over-privileged pull-requests: write entry from
the permissions block so the workflow only requests read-only token scope;
locate the permissions YAML block (the permissions: contents: read section) and
delete the pull-requests: write line (or replace it with no permission) to
ensure the job does not request PR write rights.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: bd24c0f2-07a4-4b52-85b4-40c09f4ed597

📥 Commits

Reviewing files that changed from the base of the PR and between 5acd15a and 2c8d2ca.

📒 Files selected for processing (8)
  • .github/workflows/ci-data-sanitization-log-providers.yml
  • .github/workflows/ci-data-sanitization.yml
  • .github/workflows/ci-root.yml
  • .github/workflows/ci.yml
  • docs/superpowers/plans/2026-05-26-ci-and-script-cleanup.md
  • package.json
  • packages/data-sanitization-log-providers/package.json
  • packages/data-sanitization/package.json
💤 Files with no reviewable changes (1)
  • .github/workflows/ci.yml

Comment thread .github/workflows/ci-data-sanitization-log-providers.yml
Comment thread .github/workflows/ci-data-sanitization.yml
Comment thread .github/workflows/ci-root.yml Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

Coverage Report for packages/data-sanitization-log-providers

Status Category Percentage Covered / Total
🔵 Lines 100% 57 / 57
🔵 Statements 100% 58 / 58
🔵 Functions 100% 11 / 11
🔵 Branches 100% 36 / 36
File CoverageNo changed files found.
Generated in workflow #3 for commit 9e51180 by the Vitest Coverage Report Action

ioncache and others added 2 commits May 26, 2026 23:11
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ioncache ioncache merged commit a5e262c into main May 27, 2026
8 checks passed
@ioncache ioncache deleted the feat/ci-script-cleanup branch May 27, 2026 03:18
ioncache added a commit that referenced this pull request May 27, 2026
Add a comprehensive adversarial test suite to harden coverage of the
regex-based string sanitization path and expose documented limitations.

replacers.test.ts — new 'adversarial string inputs' describe block:
- boolean, null, array, object values: not masked on regex path
  (known limitation), masked correctly with parseJsonStrings: true
- empty-string value: regex misbehaves (over-consumption); parseJsonStrings
  path handles it correctly
- escaped-quote values: regex path may garble output; parseJsonStrings path
  handles correctly; both paths never throw
- truncated / brace-less JSON fragments: no exception
- very long values (10 KB): masked successfully
- performance: two timing guards against catastrophic backtracking
- double-encoded JSON: escapedJsonMatcher catches inner fields on regex path;
  parseJsonStrings + regex fallback also suppresses the inner secret
- idempotency: sanitizing twice produces the same result
- form-encoded edge cases: empty value, base64 padding, multiple occurrences,
  URL-encoded ampersand, semicolon-delimited strings
- multiline strings: sensitive field on one line; surrounding lines preserved
- unicode escape values: masked correctly
- value-contains-key-name strings: non-sensitive keys not masked
- mixed-type arrays: string masked, number not masked on regex path; both
  masked with parseJsonStrings: true

matchers.test.ts — adversarial additions per matcher:
- formEncodedMatcher: empty value, URL-encoded ampersand, base64 padding,
  semicolon-separated strings, very long values, tab in value
- jsonMatcher: empty-string over-consumption quirk, numeric/boolean/null/array
  values not matched, unicode escapes, escaped-quote partial-match, whitespace-
  before-colon limitation, very long values, digit-suffix key names, value-only
  pattern not matched
- escapedJsonMatcher: empty-value delimiter-bleed quirk, double-escaped
  backslash, unicode sequences, very long values, multiple fields, value-only
  pattern not matched

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ioncache added a commit that referenced this pull request May 27, 2026
# Overview

Adds a comprehensive adversarial test suite to harden coverage of the
regex-based string sanitization path. The tests document known
limitations precisely — tests that expose a limitation assert the
*current* behavior so any future regression (in either direction) is
caught immediately.

## Details

**`replacers.test.ts` — new `adversarial string inputs` describe block
inside `stringReplacer`:**

- Boolean, null, array, and object field values: not masked on the regex
path (known limitation); correctly masked with `parseJsonStrings: true`
- Empty-string field values: regex over-consumes neighboring delimiter
characters ( bleeds), producing an incorrect replacement; path handles
correctly
- Escaped-quote values (`sec"ret`): regex stops at the first unescaped
`"`, may corrupt surrounding JSON; never throws; `parseJsonStrings` path
handles correctly
- Truncated and brace-less JSON fragments: no exception on either path
- Very long values (10 KB): masked successfully
- Two performance guards against catastrophic backtracking (2-second
limit)
- Double-encoded JSON: `escapedJsonMatcher` catches inner fields on the
regex path; `parseJsonStrings` path also suppresses the inner secret
- Idempotency: sanitizing twice produces the same result
- Form-encoded edge cases: empty value, base64 padding (`==`), multiple
occurrences, URL-encoded ampersand (`%26`), semicolon-delimited strings,
single key with no delimiter
- Multiline strings: sensitive field on one line, surrounding lines
preserved
- Mixed-type arrays: string value masked, number value not masked on
regex path; both masked with `parseJsonStrings: true`

**`matchers.test.ts` — adversarial additions per matcher:**

- `formEncodedMatcher`: empty value, URL-encoded ampersand, base64
padding, semicolon-separated strings (not treated as delimiters), very
long values, tab in value
- `jsonMatcher`: empty-string over-consumption quirk,
numeric/boolean/null/array values not matched (known limitation),
unicode escapes matched correctly, escaped-quote partial-match
limitation, whitespace-before-colon limitation, very long values,
digit-suffix key names, value-only pattern not matched
- `escapedJsonMatcher`: empty-value delimiter-bleed quirk,
double-escaped backslash, unicode sequences, very long values, multiple
fields in one string, value-only pattern not matched

## Related Tickets and/or Pull Requests

Relates to #316

## Checklist

- [x] Tests added or updated
- [ ] README and TSDoc updated if the public API changed
- [ ] Breaking changes called out (if any)
- [ ] Roadmap item checked off if this PR completes one

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
* Broader, more robust sanitization matching (better handling of
hyphenated field names and escape-aware quoted JSON) for more reliable
masking.
* **Tests**
* Expanded and reorganized test coverage across many edge cases:
empty/very long values, escaped/unicode sequences, delimiter/format
tolerance, tabs/whitespace, malformed/truncated inputs,
nested/double-encoded JSON, collections, idempotency, performance
bounds, and multi-occurrence masking.
* Clarified numerous test descriptions for logging and error-wrapping
behaviors.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/ioncache/data-sanitization/pull/319?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
ioncache added a commit that referenced this pull request May 27, 2026
Adds a comprehensive adversarial test suite to harden coverage of the
regex-based string sanitization path. The tests document known
limitations precisely — tests that expose a limitation assert the
*current* behavior so any future regression (in either direction) is
caught immediately.

**`replacers.test.ts` — new `adversarial string inputs` describe block
inside `stringReplacer`:**

- Boolean, null, array, and object field values: not masked on the regex
path (known limitation); correctly masked with `parseJsonStrings: true`
- Empty-string field values: regex over-consumes neighboring delimiter
characters ( bleeds), producing an incorrect replacement; path handles
correctly
- Escaped-quote values (`sec"ret`): regex stops at the first unescaped
`"`, may corrupt surrounding JSON; never throws; `parseJsonStrings` path
handles correctly
- Truncated and brace-less JSON fragments: no exception on either path
- Very long values (10 KB): masked successfully
- Two performance guards against catastrophic backtracking (2-second
limit)
- Double-encoded JSON: `escapedJsonMatcher` catches inner fields on the
regex path; `parseJsonStrings` path also suppresses the inner secret
- Idempotency: sanitizing twice produces the same result
- Form-encoded edge cases: empty value, base64 padding (`==`), multiple
occurrences, URL-encoded ampersand (`%26`), semicolon-delimited strings,
single key with no delimiter
- Multiline strings: sensitive field on one line, surrounding lines
preserved
- Mixed-type arrays: string value masked, number value not masked on
regex path; both masked with `parseJsonStrings: true`

**`matchers.test.ts` — adversarial additions per matcher:**

- `formEncodedMatcher`: empty value, URL-encoded ampersand, base64
padding, semicolon-separated strings (not treated as delimiters), very
long values, tab in value
- `jsonMatcher`: empty-string over-consumption quirk,
numeric/boolean/null/array values not matched (known limitation),
unicode escapes matched correctly, escaped-quote partial-match
limitation, whitespace-before-colon limitation, very long values,
digit-suffix key names, value-only pattern not matched
- `escapedJsonMatcher`: empty-value delimiter-bleed quirk,
double-escaped backslash, unicode sequences, very long values, multiple
fields in one string, value-only pattern not matched

Relates to #316

- [x] Tests added or updated
- [ ] README and TSDoc updated if the public API changed
- [ ] Breaking changes called out (if any)
- [ ] Roadmap item checked off if this PR completes one

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

* **Improvements**
* Broader, more robust sanitization matching (better handling of
hyphenated field names and escape-aware quoted JSON) for more reliable
masking.
* **Tests**
* Expanded and reorganized test coverage across many edge cases:
empty/very long values, escaped/unicode sequences, delimiter/format
tolerance, tabs/whitespace, malformed/truncated inputs,
nested/double-encoded JSON, collections, idempotency, performance
bounds, and multi-occurrence masking.
* Clarified numerous test descriptions for logging and error-wrapping
behaviors.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/ioncache/data-sanitization/pull/319?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
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