Skip to content

fix: make two green gates actually check something, and close the security-gate gaps - #56

Merged
webdevsamran merged 1 commit into
mainfrom
fix/gates-that-check-things
Sep 9, 2026
Merged

fix: make two green gates actually check something, and close the security-gate gaps#56
webdevsamran merged 1 commit into
mainfrom
fix/gates-that-check-things

Conversation

@webdevsamran

Copy link
Copy Markdown
Owner

The result-artifact gate validated nothing

The step named "Validate bundled result artifacts against schemas/result-v1" loaded the schema and called Draft202012Validator.check_schema(schema). That checks the schema document is well-formed JSON Schema — it never loaded an artifact. Required, branch-protected, green, and proving nothing about its own name.

Running it for real found five disagreements between the schema and the emitters. Two are genuine code defects:

Key in diff / baseline in breaking / validate Consequence
changes array of changes integer count one tool, one key, two types
operations array of per-operation stats integer count performance/engine.py reads it back as that array — a validate artifact would raise

Both counts are renamed to change_count / operation_count. Nothing consumed the integer forms; every consumer in apiverity, tests and web/ reads the array forms, untouched.

The other three were the schema being wrong: seed, target and operation_key are legitimately null when they don't apply — that's the provenance honesty this project fixed earlier — and rules, plugins, changelog and self-test emit artifacts but were absent from the command enum.

Pinned actions lied about their versions

Five uses: lines pinned actions/setup-python@5fda3b95a4ea and annotated it # v5.6.0. That SHA is v7.0.0 — two majors newer — and devrepro-doctor and local-ai-hardware-bench pin the identical SHA while correctly calling it v7.0.0. The pin is the control; the comment is what a reviewer reads.

scripts/check_action_pins.py resolves every pinned SHA against the GitHub API and fails on a comment that disagrees, or on any action not pinned at all. It verifies 30 pins here.

Security gates

pip-audit ran and nothing on the npm side, so half the dependency surface went unexamined under a green "Dependency scan". The only secret check was a local pre-commit hook that --no-verify skips and CI never ran.

  • npm audit --audit-level=high — hard gate
  • scripts/secret_scan.py in CI
  • CodeQL security-extended, matching local-ai-hardware-bench

The secret scanner needed a test more than anything else here

Planting a real-shaped secret of every class it claims to detect found it had no Slack, Google, Stripe or npm rule at all — four classes silently unchecked.

Two things worth recording:

  • I reached for Shannon entropy first. Measuring it showed the fixture sk-abcdefghijklmnop1234 scores 4.44higher than a real GitHub PAT at 4.14, because a sequential alphabet maximises character diversity. Entropy was the wrong instrument and the measurement said so. The replacement requires an ascending run to dominate the value, not merely appear in it (the first version hid a real-shaped npm token ending in 0123456789).
  • GitHub push protection rejected the first version of the test file, reading the Slack fixture as a live token. Correct on its side, and useful evidence on ours. It offered an "allow this secret" URL; taking it would teach this repo to wave detections away. The fixtures are assembled from fragments at runtime instead — the test still exercises fully-formed values, but no complete credential-shaped literal exists in the tree for anyone's scanner to trip over. That also shrank the explicit-exemption surface from twelve lines to one.

Verification

Gate Result
ruff check / ruff format --check clean
mypy clean, 90 source files
pytest 428 passed
coverage 81.12% against the 72% floor
e2e · rule catalog --check · README capture --check clean
validate_result_artifacts.py 6 artifacts validate
secret_scan.py clean, 1 marked exemption
check_action_pins.py 30 pins verified

…urity-gate gaps

**The result-artifact gate validated nothing.** The step named "Validate
bundled result artifacts against schemas/result-v1" loaded the schema and
called `Draft202012Validator.check_schema(schema)`. That checks the schema
*document* is well-formed JSON Schema; it never loaded an artifact. Required,
branch-protected, green, and proving nothing about its own name.

Running it for real (scripts/validate_result_artifacts.py, six commands
against the bundled fixtures) immediately found five disagreements between the
schema and the emitters. Two are genuine code defects, not schema pedantry:

- `changes` was the array of changes in `diff` and an integer count in
  `breaking`. Same key, two types, from one tool.
- `operations` was an integer count in `validate` and `self-test`, but the
  array of per-operation stats everywhere else -- and performance/engine.py
  reads it back as that array (`{o["operation_key"]: o for o in
  baseline["operations"]}`). Handing it a `validate` artifact would raise.

Both counts are renamed to `change_count` / `operation_count`. Nothing
consumed the integer forms; every consumer in apiverity, tests and web/ reads
the array forms, which are untouched.

The other three were the schema being wrong: `seed`, `target` and
`operation_key` are legitimately null when they do not apply -- that is the
provenance honesty this project fixed earlier -- and `rules`, `plugins`,
`changelog` and `self-test` emit artifacts but were missing from the command
enum.

**Pinned actions lied about their versions.** Five `uses:` lines pinned
actions/setup-python@5fda3b95a4ea and annotated it `# v5.6.0`. That SHA is
v7.0.0 -- two majors newer -- and devrepro-doctor and local-ai-hardware-bench
pin the identical SHA while correctly calling it v7.0.0.
scripts/check_action_pins.py resolves every pinned SHA against the GitHub API
and fails on a comment that disagrees, or on any action not pinned at all.

**Security gates.** This repository ran pip-audit and nothing on the npm side,
so half its dependency surface went unexamined under a green "Dependency scan".
Its only secret check was a local pre-commit hook that `--no-verify` skips and
CI never ran. CodeQL now uses `security-extended`, matching
local-ai-hardware-bench.

**The secret scanner needed its own test more than anything else here.**
Planting a real-shaped secret of every class it claims to detect found that it
had no Slack, Google, Stripe or npm rule at all -- four classes silently
unchecked -- and that my first placeholder heuristic hid a real-shaped npm
token because it ended in `0123456789`.

I reached for Shannon entropy first. Measuring it showed the fixture
`sk-abcdefghijklmnop1234` scores 4.44, *higher* than a real GitHub PAT at
4.14, because a sequential alphabet maximises character diversity. Entropy was
the wrong instrument and the measurement is what said so; the replacement
requires an ascending run to dominate the value rather than merely appear in
it.

GitHub's push protection then rejected the first version of the test file,
reading the Slack fixture as a live token. That is correct on its side and
useful evidence on ours -- the fixtures are realistic enough for a real
scanner to bite. It offered an "allow this secret" URL; taking it would teach
this repository to wave detections away. The fixtures are assembled from
fragments at runtime instead, so the test still exercises fully-formed values
while no complete credential-shaped literal exists in the tree for anyone's
scanner to trip over. That also shrank the explicit-exemption count from
twelve lines to one.

Verified: ruff, ruff format, mypy (90 files), 428 tests pass, coverage 81.12%
against the 72% floor, and all six repeatable gates clean (e2e, rule catalog,
README capture, result artifacts, secret scan, action pins).
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

API Verity — contract review

One comment per PR — updated on each push.

@webdevsamran
webdevsamran merged commit fce6872 into main Sep 9, 2026
13 checks passed
@webdevsamran
webdevsamran deleted the fix/gates-that-check-things branch September 9, 2026 09:44
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