Skip to content

docs: honesty pass on the default filter, and fix changelog attributions - #5

Merged
higagan merged 2 commits into
mainfrom
docs/honesty-pass
Jul 30, 2026
Merged

docs: honesty pass on the default filter, and fix changelog attributions#5
higagan merged 2 commits into
mainfrom
docs/honesty-pass

Conversation

@higagan

@higagan higagan commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Version → 0.3.3. Documentation only; no code changes. 60 tests still pass.

1. README — the honesty pass

Quickstart note, verbatim as specified:

Note: When used bare, @shield_tool applies a default PolicyEngine with a basic SensitiveDataFilter. For production use, define your own rules (like URLAllowList or custom secret scanners) and pass your own engine: @shield_tool(engine=my_engine).

How It Works — the @shield_tool bullet now covers sync/async and the stderr warning, as specified. I also added file:// to the Default Deny bullet, since 0.3.2 shipped scheme checking and nothing documented it.

New ## Limitations section, as specified. Two deviations from your text, both deliberate:

  • v0.3.2v0.3.3, because this PR ships as 0.3.3 and the text would have been wrong on arrival.
  • ## not ###, to sit at the same level as the sections around it. Your instruction said ## Limitations; the pasted block said ###.

2. CHANGELOG — wider than the four items you asked for

You asked me to move four items into a 0.2.2 section. Checking against the tags, the drift was systematic — the whole 0.2.x range was one release out of step, so fixing only four would have left it wrong in three more places:

Actual range Contents Where the CHANGELOG had filed them
v0.2.0..v0.2.1 confused-deputy payloads under 0.2.0
v0.2.1..v0.2.2 eight doc commits three under 0.2.1, five under 0.3.0
v0.2.2..v0.3.0 the adaptive fuzzer only correct, plus five borrowed items

So it was five items misfiled under 0.3.0, not four — docs: show real demo.py and modelfuzz scan output also predates the v0.2.2 tag. And 0.2.2 had no section at all despite being on PyPI.

Corrected so each section matches its tag range. The link footer stopped at [0.2.1], which made ## [0.3.x] headings render as literal bracket text on GitHub and PyPI; it now covers 0.2.2 → 0.3.3.

Still not fixed: 0.1.1 is on PyPI with no CHANGELOG section and no tag. I left it alone rather than invent contents for it.

3. Shell cleanup (outside the repo)

Removed the dead UV_PUBLISH_TOKEN line from ~/.zshrc — broken syntax holding the revoked token. Verified the working token still resolves from ~/.zshenv and the interactive shell no longer errors. Backups at ~/.zshrc.bak-modelfuzz / ~/.zshenv.bak-modelfuzz.

higagan added 2 commits July 30, 2026 15:31
The README described the bare @shield_tool as blocking "common secrets
(API keys, passwords)". It does not: SensitiveDataFilter substring-matches
the words secret/password/api_key, so a real sk-... or AKIA... credential
passes straight through while benign prose containing "password" is blocked.
The Quickstart note now says what the filter is, and a Limitations section
states that it is not a secret-detection engine.

Also documents behaviour shipped in 0.3.2 but never written down: the
decorator handles sync and async functions, blocks log a structured warning
to stderr, and URLAllowList rejects disallowed schemes.

The 0.2.x changelog sections were one release out of step with the tags.
Verified against the actual ranges:
  v0.2.0..v0.2.1  confused-deputy payloads       (was filed under 0.2.0)
  v0.2.1..v0.2.2  eight doc commits              (three were filed under
                                                  0.2.1, five under 0.3.0)
  v0.2.2..v0.3.0  the adaptive fuzzer only
0.2.2 had no section at all despite being on PyPI. Added, and the link
footer now covers 0.2.2 through 0.3.3.
The first Limitations wording said the default filter was "basic keyword
matching" and "not a substitute for a dedicated secret-scanning engine" --
true but abstract. It never told the reader the fact that matters: a real
sk-... or AKIA... credential passes straight through. Vagueness in the one
section whose job is disclosure reads as hedging, so it now names the three
literal strings it matches and says plainly what it misses.

Every claim in the section was verified against the code:
  sk- / AKIA keys      pass through
  dict keys, bytes,    not inspected
  sets, objects
  policies see one argument at a time, never the whole call

The hosted dashboard moved to its own Roadmap section. A product pitch inside
a Limitations block invites the reading that the gap is a business decision,
which is the standard criticism of open-core security tooling.
@higagan

higagan commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

Amended: Limitations rewritten, Roadmap split out

Pushed as 20bd5e5.

## Limitations now reads:

ModelFuzz provides the interception point, the policy protocol, and an adaptive fuzzer. The default SensitiveDataFilter matches the literal strings secret, password, and api_key — it does not recognise credential formats, so a real sk-… or AKIA… key will pass through it. Treat it as a demo default and write policies for your own threat model. Also: policies see each argument in isolation, not the whole call, and only str, list, tuple, and dict values are inspected.

## Roadmap is now a separate section:

A hosted dashboard is in development, providing centralized audit logs, policy versioning, and managed secret detection.

Every factual claim was verified against the code before pushing:

default keywords: ['secret', 'password', 'api_key']

sk- key      -> passes through
AKIA key     -> passes through

str          -> inspected (BLOCKED)
list         -> inspected (BLOCKED)
tuple        -> inspected (BLOCKED)
dict value   -> inspected (BLOCKED)
dict KEY     -> NOT inspected (passes)
bytes        -> NOT inspected (passes)
set          -> NOT inspected (passes)
object attr  -> NOT inspected (passes)
dataclass    -> NOT inspected (passes)

Two notes:

  • Heading is ##, not ### as pasted, so it sits level with the sections around it — same call as the previous round.
  • "only str, list, tuple, and dict values are inspected" is accurate but compact. It's literally true, and it correctly implies that bytes, sets, and objects are not — but it doesn't spell out that dict keys are also skipped, so {"api_key": "sk-12345"} passes. Happy to make that explicit if you want the section to leave nothing to inference.

Also dropped the hardcoded v0.3.3 from the text, so the section won't go stale on the next release.

@higagan
higagan merged commit cbfdf90 into main Jul 30, 2026
3 checks 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