GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Make every API-sourced enum forward-compatible, and detect drift proactively by lelia · Pull Request #107 · SocketDev/socket-sdk-python

Conversation

@lelia

@lelia lelia commented Sep 2, 2026 •
edited by cursor Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Five of the six enums populated from API responses coerced strictly, so any value the backend added would raise ValueError inside from_dict and empty an entire response rather than degrade one field. That is the mechanism behind issue #78 and the unknown generic purl type. Each was fixed on the single enum that happened to fire, leaving the other five holding the same landmine.

This fixes the class rather than the next instance, and adds a check that finds the next one before a customer does.

Forward-compatible enums

SocketIssueSeverity, SocketCategory, DiffType, ScanType and SecurityAction now fall back to a documented member and log the unrecognized value. SocketPURL_Type already did; its inline implementation now routes through one shared helper in socketdev/core/enums.py so all six behave and log identically. The dead try/except in SocketAlert.from_dict is removed, since _missing_ covers every coercion path rather than that one call site.

The fallbacks are chosen, not convenient:

Enum Fallback Why not something else
SocketIssueSeverity new UNKNOWN LOW hides a serious finding, CRITICAL manufactures one
DiffType new UNKNOWN UNCHANGED would silently drop a real diff entry
ScanType new UNKNOWN no safe existing default
SocketCategory MISCELLANEOUS matches the existing convention
SecurityAction DEFER already means "use the configured default"; IGNORE disables a rule, ERROR fails builds
Worth a second opinion: SecurityAction

DEFER is inferred from the action descriptions in the OpenAPI spec rather than from backend code. If defer does not mean "fall through to the org default" in every context this enum is parsed from, a new UNKNOWN sentinel would be the safer choice.

Enforced as an invariant

tests/unit/test_enum_forward_compat.py walks the package, discovers every enum including ones added later, and fails if any raises on an unrecognized value. It also asserts the fallback is a real member of its own enum, that the warning names the enum, and that known values still round-trip.

Two details that matter: a test_enums_are_discovered guard prevents a broken walk from making every other assertion vacuously pass, and a documented REQUEST_ONLY_ENUMS opt-out (currently empty) gives a future request-building enum a legitimate escape hatch — strictness is correct where the value comes from the caller, not the API.

Drift detection with no setup

scripts/check_api_enum_drift.py compares the SDK's enums against https://api.socket.dev/v0/openapi. That spec is public and unauthenticated, so this needs no token, no org and no fixture data.

It immediately found ten purl types the API defines and this SDK did not know about, all of which were being flattened to unknown: alpm, chrome, clawhub, edge-extension, firefox-extension, qpkg, socket, swid, vscode, vscode-extension. Those are added here.

Missing values fail. SDK-only values warn rather than fail, since dropping a member would be breaking and the spec omitting one is usually a spec gap. The two enums the spec exposes no named schema for (ScanType, SecurityAction) are reported as uncovered rather than silently skipped.

.github/workflows/api-drift-check.yml runs it. It is workflow_dispatch-only for now, with the weekly schedule commented and a TODO to enable once it has run green by hand a few times. Deliberately not a pull_request trigger: it tests the API, not the diff, and a backend change must never block an unrelated SDK pull request.

Also in here

  • Linear IDs removed from two pre-existing test docstrings. Ticket identifiers belong in the pull request description, not in code that outlives the ticket. The GitHub issue reference stays, since that resolves for anyone reading the repo.
  • .gitattributes plus a one-time line-ending normalization. Eleven Python files were committed with CRLF, socketdev/__init__.py among them, so any tooling that rewrites one converts it to LF and turns a two-line edit into a whole-file diff. That happened while writing this branch. Isolated in its own commit and reviewable with git diff -w, which shows only .gitattributes — no file content changed.

Verification

  • 149 passed, 1 skipped, 84 subtests, including both pre-existing regression tests unmodified
  • Drift check exits 0; negative-tested by deleting two purl members, which correctly produced exit 1 naming them
  • ruff check clean on all touched files
  • Version bumped to 3.6.0: additive members plus a behavior change, no breakage

Note

Medium Risk
Changes how unknown severities, diff types, categories, and security actions are represented at parse time (fallbacks instead of errors), which affects downstream reporting and policy behavior until the SDK is updated.

Overview
3.6.0 hardens the SDK against API enum drift so a single unknown value no longer fails entire scan/diff parses (the failure mode behind issue #78 and unknown purl types).

Response-parsed enums (SocketIssueSeverity, SocketCategory, DiffType, SecurityAction, and SocketPURL_Type) now use shared _missing_ handling via socketdev/core/enums.py: log a warning and return a documented fallback (UNKNOWN for severity/diff, MISCELLANEOUS for category, DEFER for security actions, UNKNOWN for purl types). ScanType stays strict because it is only sent on create-scan requests. Ten missing SocketPURL_Type members from the live API are added so those artifacts are no longer coerced to unknown. SocketAlert.from_dict drops its bespoke category try/except in favor of enum _missing_.

Guardrails: tests/unit/test_enum_forward_compat.py discovers all package enums and enforces tolerant parsing (with an explicit request-only opt-out for ScanType). scripts/check_api_enum_drift.py compares enums to the public OpenAPI spec; .github/workflows/api-drift-check.yml runs it on manual dispatch only (not on PRs). .gitattributes pins LF line endings to stop CRLF-only noise in future diffs. Version bumped to 3.6.0 with changelog updates.

Reviewed by Cursor Bugbot for commit 2d72644. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
lelia and others added 3 commits September 2, 2026 18:26
@lelia @claude
feat(enums): make every API-sourced enum forward-compatible
bc5b3b7
Five of the six enums populated from API responses coerced strictly, so a
value the backend added would raise ValueError inside from_dict and empty an
entire response rather than degrade one field. That is the mechanism behind
issue #78 and the unknown `generic` purl type; each was fixed on the single
enum that fired, leaving the rest holding the same landmine.

All five now fall back to a documented member and log the unrecognized value.
The fallbacks are chosen rather than convenient: SocketIssueSeverity and
DiffType gain an explicit UNKNOWN, since guessing an existing level would
either hide a real finding or invent one, and SecurityAction defers.

A generalized test discovers every enum in the package, including ones added
later, and fails if any raises. A drift check compares the enums against the
public OpenAPI spec; it found 10 purl types the SDK was missing, which are
added here.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@lelia @claude
docs: drop Linear IDs from test docstrings and comments
d99483b
Ticket identifiers belong in the pull request description, not in code that
outlives the ticket. The GitHub issue reference in the purl test docstring
stays, since that resolves for anyone reading the repository.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@lelia @claude
chore: add .gitattributes and normalize line endings to LF
203b5e8
Eleven Python files were committed with CRLF, socketdev/__init__.py among them.
Any tooling that reads and rewrites one of those files converts it to LF on the
way out, so a two-line edit arrives as a whole-file diff with the real change
buried in it. That happened while writing the enum change in this same branch.

This normalizes all of them once and pins the setting so it cannot recur.
Reviewable with `git diff -w`, which shows only .gitattributes: no file content
changed, and the unit suite is unaffected.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@lelia
lelia requested a review from a team as a code owner September 2, 2026 22:27
@lelia lelia changed the title Make every API-sourced enum forward-compatible, and detect drift before a customer does Make every API-sourced enum forward-compatible, and detect drift proactively Sep 2, 2026
cursor[bot]
cursor Bot reviewed Sep 2, 2026
View reviewed changes
Comment thread socketdev/fullscans/__init__.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

lelia and others added 3 commits September 2, 2026 18:37
@lelia
Merge branch 'main' into chore/enum-forward-compat-and-drift-check
2d48a4f
@lelia @claude
fix(enums): keep ScanType strict, it only ever builds requests
d7bc034
ScanType never parses an API response. FullScanParams.to_dict() is urlencoded
onto the create-scan query string, so giving it a _missing_ fallback meant a
caller typo silently shipped scan_type=unknown to the API instead of failing at
construction. The same from_dict already passes integration_type through
uncoerced for that reason.

It is now recorded in REQUEST_ONLY_ENUMS, the opt-out the invariant test always
had and this branch had left empty, and a new test asserts request-only enums
keep raising so the exemption cannot quietly become a skip.

Also bumps actions/setup-python in the new workflow to v7.0.0, matching the pin
already used by .github/actions/setup-sfw.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@lelia
Merge remote branch state (main merge) into ScanType fix
2d72644
@lelia

lelia commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

bugbot run

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@lelia lelia mentioned this pull request Sep 2, 2026
Normalize Slack issue severity and bump SDK to v3.6.0 SocketDev/socket-python-cli#331
Merged
cursor[bot]
cursor Bot reviewed Sep 2, 2026
View reviewed changes

@cursor cursor Bot left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 2d72644. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
flowstate
Eric Hibbs (flowstate) approved these changes Sep 9, 2026
View reviewed changes

@flowstate Eric Hibbs (flowstate) left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

[agent] Read the real diff (the raw stat is inflated by an isolated CRLF-to-LF normalization commit, isolated cleanly per the PR description and verified with git diff -w) -- enum definitions, the shared _missing_ helper, the new invariant test, and the drift-check script.

Every fallback is deliberately chosen and justified inline rather than defaulted to something convenient (DEFER for SecurityAction because it already means 'use the org default', a new UNKNOWN for severity/diff-type rather than guessing an existing level). ScanType correctly stays strict since it's outbound-only, and the commit history shows that got caught and fixed before this landed, with a test that now actively asserts it stays strict rather than just not-currently-tolerant.

test_enum_forward_compat.py enforcing this generically across the whole package, including future enums, rather than adding a fourth bespoke regression test, is the right level of fix for a bug class that's already recurred twice. The drift script's scope (public spec, manual-dispatch only, not a pull_request trigger) is exactly right for what it's testing.

No findings.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

lelia reacted with rocket emoji
All reactions
  • 🚀 1 reaction
@lelia
Merge branch 'main' into chore/enum-forward-compat-and-drift-check
6dbcf7f
@lelia
lelia merged commit 57d1bc5 into main Sep 9, 2026
12 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@lelia
lelia deleted the chore/enum-forward-compat-and-drift-check branch September 9, 2026 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@cursor cursor[bot] cursor[bot] left review comments
@flowstate Eric Hibbs (flowstate) flowstate approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@lelia @flowstate
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.