Skip to content

privacy scan, array param fix, and the dead command builder - #32

Merged
lucianfialho merged 1 commit into
mainfrom
feat/privacy-scan-and-cleanup
Aug 3, 2026
Merged

lucianfialho merged 1 commit into
mainfrom
feat/privacy-scan-and-cleanup

Conversation

@lucianfialho

Copy link
Copy Markdown
Owner

Three things that came out of clearing the backlog.

privacy scan

--filter-pii shipped without any way to see what it touches. That is a bad trade in both directions: too little and personal data reaches the model anyway, too much and a field the caller needed comes back redacted with no hint why.

$ spec2cli privacy scan ./api.yaml
Shop API

4 fields would be redacted:

  Customer
    email
    full_name
    phone
    cpf

Returned by:
  GET /customers

--output json gives the field list as data. Detection is by field name and format, so an unusually named field is missed — which is precisely the reason to be able to look. Addresses the reporting half of #22; runtime filtering already existed.

Array params were sent as strings

The extractor names an array type after its items — string[], not array — so the check for structured types never matched. --tags '["a","b"]' reached the server as a quoted string rather than an array.

This had a passing test. The test hand-built its Operation with type: "array", a value the extractor never produces, so it exercised a shape that does not occur and stayed green while the real path was broken. Rewriting it to go through the extractor is what surfaced the bug.

The dead command builder

src/executor/commander-builder.ts had not been on the runtime path for some time. It duplicated command building and had already drifted — #31 changed it while the live path moved on. That is the same shape of divergence that let --dry-run print credentials in the clear, so it is deleted rather than fixed.

Its JSON-parameter tests are replaced against dynamic-commands.ts.

Also

bench/harness/lean-agent.mjs — the experiment that would settle the Phase B question. The ~880-operation crossover is a property of the agent: Claude Code resends ~31k tokens per turn, which is what makes a discovery step expensive. A lean loop resends far less and should cross over much sooner. It needs ANTHROPIC_API_KEY and has not been run; if context-per-turn lands near 2k rather than 31k, PROGRESSIVE_THRESHOLD should come down.

Testing

212 tests, up from 209 — net of 12 deleted with the dead module and 15 added.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QpcUFZcRHNurdJ2diVg37T

`privacy scan` reports the fields the filter would touch, grouped by schema, and
which operations return them:

  $ spec2cli privacy scan ./api.yaml
  4 fields would be redacted:
    Customer
      email, full_name, phone, cpf
  Returned by:
    GET /customers

Turning the filter on without being able to see its reach was a bad trade in
both directions: too little and personal data goes out anyway, too much and a
field the caller needed comes back redacted with no hint why. Detection is by
name and format, so an unusually named field is missed — which is the reason to
be able to look. Part of #22; the runtime filtering half already shipped.

Array parameters given as JSON were sent as raw strings. The extractor names an
array after its items — `string[]`, not `array` — so the check for structured
types never matched and `["a","b"]` reached the server quoted.

The dead commander-builder module is gone. It had not been on the runtime path
for some time, duplicated command building, and had already drifted: #31 changed
it while the live path moved on. That is the same shape of divergence that let
--dry-run print credentials in the clear.

Its JSON-parameter tests are replaced against the live path, and doing so is what
surfaced the array bug: the old ones hand-built their Operation objects with
`type: "array"`, a value the extractor never produces, so they passed while the
behaviour they claimed to cover was broken.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QpcUFZcRHNurdJ2diVg37T
@lucianfialho
lucianfialho merged commit 78293a1 into main Aug 3, 2026
1 check passed
@lucianfialho
lucianfialho deleted the feat/privacy-scan-and-cleanup branch August 3, 2026 00:40
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