Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: SocketDev/socket-python-cli
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6076acf
Choose a base ref
...
head repository: SocketDev/socket-python-cli
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ad62842
Choose a head ref
  • 19 commits
  • 64 files changed
  • 5 contributors

Commits on Sep 4, 2026

  1. Make tar_hash required for reachability analysis (#341)

    run_reachability_analysis() always receives a manifest tar hash from its
    only caller, so drop the Optional default and the conditional that skipped
    --run-without-docker/--manifests-tar-hash when it was absent.
    
    Pass tar_hash at the test call sites accordingly.
    BarrensZeppelin authored Sep 4, 2026
    Configuration menu
    Copy the full SHA
    4601aa1 View commit details
    Browse the repository at this point in the history
  2. Apply ruff autofixes and add a ruff CI job (#342)

    * Apply ruff autofixes for imports and lint nits
    
    Result of `uv run ruff check --fix --unsafe-fixes`: sort and regroup
    imports (isort), drop unused imports, remove f-string prefixes from
    strings with no placeholders, drop unused bindings, and simplify
    `== True`/`== False` assertions to truthiness checks.
    
    * Add a ruff job to the unit test workflow
    
    Mirrors the checkout and python setup from python-tests. Installs the
    dev extra rather than test, since that is where the ruff pin lives.
    BarrensZeppelin authored Sep 4, 2026
    Configuration menu
    Copy the full SHA
    eb3e46a View commit details
    Browse the repository at this point in the history

Commits on Sep 8, 2026

  1. Bump pinned @coana-tech/cli to 15.10.39 (#347)

    Co-authored-by: socket-pr-bot[bot] <294242679+socket-pr-bot[bot]@users.noreply.github.com>
    socket-pr-bot[bot] authored Sep 8, 2026
    Configuration menu
    Copy the full SHA
    536d3a5 View commit details
    Browse the repository at this point in the history
  2. chore(deps): bump brotlicffi from 1.2.0.1 to 1.2.0.2 (#340)

    Bumps [brotlicffi](https://github.com/python-hyper/brotlicffi) from 1.2.0.1 to 1.2.0.2.
    - [Changelog](https://github.com/python-hyper/brotlicffi/blob/main/HISTORY.rst)
    - [Commits](python-hyper/brotlicffi@v1.2.0.1...v1.2.0.2)
    
    ---
    updated-dependencies:
    - dependency-name: brotlicffi
      dependency-version: 1.2.0.2
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 8, 2026
    Configuration menu
    Copy the full SHA
    9aebab4 View commit details
    Browse the repository at this point in the history
  3. chore(deps): bump the python-minor-patch group across 1 directory wit…

    …h 2 updates (#339)
    
    Bumps the python-minor-patch group with 2 updates in the / directory: [ruff](https://github.com/astral-sh/ruff) and [uv](https://github.com/astral-sh/uv).
    
    
    Updates `ruff` from 0.16.4 to 0.16.5
    - [Release notes](https://github.com/astral-sh/ruff/releases)
    - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
    - [Commits](astral-sh/ruff@0.16.4...0.16.5)
    
    Updates `uv` from 0.12.5 to 0.12.8
    - [Release notes](https://github.com/astral-sh/uv/releases)
    - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
    - [Commits](astral-sh/uv@0.12.5...0.12.8)
    
    ---
    updated-dependencies:
    - dependency-name: ruff
      dependency-version: 0.16.5
      dependency-type: direct:production
      update-type: version-update:semver-patch
      dependency-group: python-minor-patch
    - dependency-name: uv
      dependency-version: 0.12.7
      dependency-type: direct:production
      update-type: version-update:semver-patch
      dependency-group: python-minor-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 8, 2026
    Configuration menu
    Copy the full SHA
    f0b8a9f View commit details
    Browse the repository at this point in the history
  4. ci(deps): bump docker/setup-buildx-action (#338)

    Bumps the github-actions-minor-patch group with 1 update in the /.github/actions/setup-docker directory: [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action).
    
    
    Updates `docker/setup-buildx-action` from 4.2.0 to 4.3.0
    - [Release notes](https://github.com/docker/setup-buildx-action/releases)
    - [Commits](docker/setup-buildx-action@bb05f3f...37fe631)
    
    ---
    updated-dependencies:
    - dependency-name: docker/setup-buildx-action
      dependency-version: 4.3.0
      dependency-type: direct:production
      update-type: version-update:semver-minor
      dependency-group: github-actions-minor-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: lelia <2418071+lelia@users.noreply.github.com>
    dependabot[bot] and lelia authored Sep 8, 2026
    Configuration menu
    Copy the full SHA
    86e3c1d View commit details
    Browse the repository at this point in the history

Commits on Sep 9, 2026

  1. chore(deps): bump httpcore2 from 2.9.1 to 2.10.0 (#348)

    Bumps [httpcore2](https://github.com/pydantic/httpx2) from 2.9.1 to 2.10.0.
    - [Release notes](https://github.com/pydantic/httpx2/releases)
    - [Commits](pydantic/httpx2@v2.9.1...v2.10.0)
    
    ---
    updated-dependencies:
    - dependency-name: httpcore2
      dependency-version: 2.10.0
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 9, 2026
    Configuration menu
    Copy the full SHA
    9e56d79 View commit details
    Browse the repository at this point in the history
  2. chore(deps): bump httpx2 from 2.10.0 to 2.12.0 (#349)

    Bumps [httpx2](https://github.com/pydantic/httpx2) from 2.10.0 to 2.12.0.
    - [Release notes](https://github.com/pydantic/httpx2/releases)
    - [Changelog](https://github.com/pydantic/httpx2/blob/main/src/httpx2/CHANGELOG.md)
    - [Commits](pydantic/httpx2@v2.10.0...v2.12.0)
    
    ---
    updated-dependencies:
    - dependency-name: httpx2
      dependency-version: 2.12.0
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 9, 2026
    Configuration menu
    Copy the full SHA
    e50b3aa View commit details
    Browse the repository at this point in the history
  3. Improve monorepo scan diagnostics and guidance (#325)

    * Improve monorepo scan diagnostics
    
    * Bump version to 2.6.9
    
    * Bump version to 2.7.0
    
    * docs: document the monorepo scan layout trade-off
    
    The mechanics of --sub-path and --workspace-name were documented, but not the
    choice they force. One combined scan gives a single dashboard entry and no
    per-component attribution; one scan per component gives attribution, baselines
    and per-component policy, but adds a repository entry per component, which grows
    the dashboard's repository list. There is no layout that provides both today.
    
    Customers hit this at a dozen-plus components and reasonably assume they have
    configured something wrong. Naming the trade-off, and adding rules of thumb for
    picking a side, is cheaper than each of them discovering it.
    
    Cross-referenced from the CI/CD guide's independent-workspace pattern, which is
    the layout that grows the list.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
    lelia and claude authored Sep 9, 2026
    Configuration menu
    Copy the full SHA
    f65b6af View commit details
    Browse the repository at this point in the history
  4. Normalize Slack issue severity and bump SDK to v3.6.0 (#331)

    * fix(slack): normalize the API's "middle" severity to "medium"
    
    Every severity lookup in the Slack reachability formatter is keyed on "medium",
    but "middle" is what the API sends. A mid-severity finding missed all of them
    at once: uncounted in the summary, excluded from total_findings so the "and N
    more" count can go negative, and sorted at the default order of 4 -- below
    "low" -- so it was truncated out of the message first.
    
    Normalized at the point the alert is read rather than by adding a parallel key
    to each dict, so one canonical spelling flows downstream. The GitLab severity
    map and the PR comment path already accept both forms; this formatter did not.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * chore(deps): bump socketdev to 3.6.0
    
    Unblocks the pin now that 3.6.0 is on PyPI. SocketPURL_Type gained ten
    members -- alpm, chrome, clawhub, edge-extension, firefox-extension, qpkg,
    socket, swid, vscode and vscode-extension -- and removed none, so artifacts
    of those types stop falling back to "unknown".
    
    No other CLI change is needed: none of the SDK's enum types are imported
    here, and every severity and type lookup already has a default, so the new
    members cannot reach an unguarded branch.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * ci: only floor the version check at the latest published release
    
    The check required the PR version to exceed both main and PyPI. Comparing
    against main forbids the legitimate case where several PRs ship under one
    unreleased version: the first bumps main, and the rest ride it without
    bumping again so they stay under a single changelog header. Every such PR
    failed, and the only way to green it was a throwaway bump that would strand
    a changelog header on a version that never ships.
    
    PyPI is now the floor, since the real invariant is that a release cannot
    reuse a published version. Main is still a floor in the one direction that
    matters: a PR may leave the version alone or move it forwards, never back.
    Every genuine failure the old check caught -- forgetting to bump, reusing a
    published version, branching from a stale base -- still fails.
    
    Also added this workflow to its own paths filter so a change to the check is
    exercised by the PR that makes it.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * ci: require pyproject.toml and __init__.py versions to agree
    
    The version lives as two hand-maintained literals with nothing deriving one
    from the other: pyproject.toml is what gets published, and __init__.py is
    what the CLI reports as its User-Agent. Every comparison in this job read
    only __init__.py, so bumping that alone passed the check and then published
    under the old number -- surfacing late, as twine rejecting an existing file,
    after the merge.
    
    Both are now required to match before any other comparison runs. uv.lock
    carries a third copy, but uv derives it and `uv lock --locked` in
    python-tests already fails when it drifts, so it needs no check here.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
    lelia and claude authored Sep 9, 2026
    Configuration menu
    Copy the full SHA
    860b8ea View commit details
    Browse the repository at this point in the history

Commits on Sep 11, 2026

  1. chore(deps): bump the python-minor-patch group with 2 updates (#351)

    Bumps the python-minor-patch group with 2 updates: [ruff](https://github.com/astral-sh/ruff) and [uv](https://github.com/astral-sh/uv).
    
    
    Updates `ruff` from 0.16.5 to 0.16.6
    - [Release notes](https://github.com/astral-sh/ruff/releases)
    - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
    - [Commits](astral-sh/ruff@0.16.5...0.16.6)
    
    Updates `uv` from 0.12.8 to 0.12.9
    - [Release notes](https://github.com/astral-sh/uv/releases)
    - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
    - [Commits](astral-sh/uv@0.12.8...0.12.9)
    
    ---
    updated-dependencies:
    - dependency-name: ruff
      dependency-version: 0.16.6
      dependency-type: direct:production
      update-type: version-update:semver-patch
      dependency-group: python-minor-patch
    - dependency-name: uv
      dependency-version: 0.12.9
      dependency-type: direct:production
      update-type: version-update:semver-patch
      dependency-group: python-minor-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 11, 2026
    Configuration menu
    Copy the full SHA
    3070e43 View commit details
    Browse the repository at this point in the history
  2. ci(deps): bump docker/setup-qemu-action (#350)

    Bumps the github-actions-minor-patch group with 1 update in the /.github/actions/setup-docker directory: [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action).
    
    
    Updates `docker/setup-qemu-action` from 4.2.0 to 4.3.0
    - [Release notes](https://github.com/docker/setup-qemu-action/releases)
    - [Commits](docker/setup-qemu-action@96fe6ef...1f40c72)
    
    ---
    updated-dependencies:
    - dependency-name: docker/setup-qemu-action
      dependency-version: 4.3.0
      dependency-type: direct:production
      update-type: version-update:semver-minor
      dependency-group: github-actions-minor-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: lelia <2418071+lelia@users.noreply.github.com>
    dependabot[bot] and lelia authored Sep 11, 2026
    Configuration menu
    Copy the full SHA
    962306c View commit details
    Browse the repository at this point in the history
  3. Bump pinned @coana-tech/cli to 15.10.40 (#352)

    Co-authored-by: socket-pr-bot[bot] <294242679+socket-pr-bot[bot]@users.noreply.github.com>
    Co-authored-by: lelia <2418071+lelia@users.noreply.github.com>
    socket-pr-bot[bot] and lelia authored Sep 11, 2026
    Configuration menu
    Copy the full SHA
    6864479 View commit details
    Browse the repository at this point in the history

Commits on Sep 15, 2026

  1. Bump pinned @coana-tech/cli to 15.10.41 (#354)

    Co-authored-by: socket-pr-bot[bot] <294242679+socket-pr-bot[bot]@users.noreply.github.com>
    socket-pr-bot[bot] authored Sep 15, 2026
    Configuration menu
    Copy the full SHA
    2dd3001 View commit details
    Browse the repository at this point in the history
  2. Fix GitLab report links, identifiers and locations, and make diff bas…

    …elines resilient (#337)
    
    * fix(gitlab): stabilize report data
    
    * chore: bump version to 2.8.1
    
    * fix(gitlab): harden implicit diff baseline resolution
    
    The workspace-scoped head scan lookup treated any failed request as "no
    baseline". The SDK logs and returns {} for every non-200, so a transient API
    error resolved to None, and create_new_diff answers None by creating an empty
    baseline scan -- reporting every dependency in the repository as newly added.
    An absent "results" key now raises APIFailure, and resolve_base_full_scan_id
    surfaces it the same way a missing --base-commit-sha baseline is surfaced.
    
    Selecting the newest scan on the default branch also reintroduced temporary
    scans, which the repository head pointer had excluded. The empty baseline scan
    that create_new_diff creates inherits the branch and commit of the run that
    created it, so a default-branch run whose real scan fails leaves that empty scan
    as the newest one. Both baseline lookups now skip tmp scans.
    
    Also unwrap scan_type before it is URL encoded. FullScanParams types it as a
    ScanType enum, and urlencode renders a (str, Enum) member as its repr-style
    name, which would filter on a scan type that does not exist.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(gitlab): match snake_case vulnerability ids in report identifiers
    
    Issue.props reaches the GitLab formatter from several sources, and
    core.alert_selection already matches both ghsaId/ghsa_id and cveId/cve_id when
    deciding reachability. The identifier extractor only read the camelCase
    spellings, so an alert carrying ghsa_id was selected for the report but emitted
    with only its socket_alert identifier -- the CVE and GHSA values GitLab dedupes
    and links on were dropped.
    
    Values that are neither a string nor a sequence are now skipped rather than
    iterated, so a malformed prop cannot raise out of the whole report.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * test: use a generic package name in the namespace normalization fixture
    
    The fixture named a real organization. Public test data should not, so use the
    reserved com.example namespace instead.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(gitlab): use colon-separated Maven coordinates in package links
    
    Socket addresses Maven package pages as groupId:artifactId. The CLI emitted the
    slash-separated form, so every Maven package link 404'd -- the dashboard's Maven
    handler rejects the slash form outright with "Maven package must have a colon".
    Removing the enum leak from these URLs fixed how they looked without fixing where
    they pointed.
    
    The separator now follows the ecosystem, via Package.socket_url, which both the
    full-scan and diff construction paths call. Previously each built its URL inline
    and they disagreed on namespace handling, so the same package could produce
    different links depending on which path ran.
    
    Purl strings are deliberately left on the slash form for every ecosystem: that is
    what the purl spec defines and what Socket's purl API consumes. Only the
    dashboard URL is ecosystem-dependent.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * docs: tighten comments added by this branch
    
    The Maven separator rule was explained in three places and the enum-unwrapping
    rule in two. Each now has one home: the separator at URL_NAMESPACE_SEPARATORS
    where it is defined, the enum behavior at each helper that depends on it, stated
    once rather than narrated.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(gitlab): warn when a Maven coordinate has no namespace
    
    An ecosystem with its own URL separator cannot be addressed without both halves
    of the coordinate. A Maven artifact that arrives with no groupId still gets a
    link so the finding reports, but that link cannot resolve, and previously it was
    emitted silently. It now logs a warning naming the package.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(gitlab): separate namespace and name with a slash, not a colon
    
    Reverts the separator introduced two commits ago. It rested on a report that the
    slash form does not resolve, which has since failed to reproduce: every affected
    link in that report loads, and the report's own screenshots show a working
    slash-form link.
    
    The defect those links actually exhibit is a namespace and name fused with no
    separator at all, which yields one path segment that cannot be split back into
    two. A slash fixes that and matches what the other package construction path has
    always emitted.
    
    The missing-namespace warning is kept and re-aimed: an absent namespace is what
    produces the unsplittable single segment, so that is the case worth surfacing.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * chore: bump version to 2.8.2
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(gitlab): report a real manifest and real directness in report locations
    
    Two defects in the same location block.
    
    The manifest path fell back to "unknown" whenever a package had no introducing
    chain. That happens routinely for a transitive package whose top-level ancestors
    are absent from the scan's package set, which a diff-scoped run causes by
    construction. The package records its own manifest files regardless, so those
    are now used before giving up.
    
    Directness was inferred by looking for " > " in the introducing entry, but no
    producer emits that separator -- get_source_data yields either ("direct", files)
    or (ancestor_purl, files). Every finding was therefore reported as direct,
    including transitive ones. It now comes from the package record.
    
    The dependency chain was also parsed into a local that was never read, and the
    docstring advertised a dependency_path key the function never returned. Both are
    removed rather than wired up, since the GitLab schema expects dependency
    references rather than a name path.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(gitlab): omit an absent identifier url instead of sending null
    
    The GitLab dependency-scanning schema types an identifier's url as a string
    matching ^(https?|ftp)://, so a null fails validation. The socket_alert
    identifier emitted null whenever an alert carried no url, which invalidates that
    finding for every consumer that validates the report.
    
    Verified against the published schema: a report containing an alert with no url
    now produces zero validation errors.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * feat(gitlab): fall back to the nearest scanned ancestor for --base-commit-sha
    
    A merge base can have no full scan even when default-branch scanning is
    configured and running: squash merges and rebases rewrite commits, and a
    multi-commit push produces one scan for the tip while leaving the commits in
    between unscanned. Any of those turned every open merge request into a failed
    pipeline, because a missing baseline was a hard stop with no degraded mode.
    
    The requested commit is still preferred. When it has no scan, one listing of
    recent scans is matched against local first-parent history and the nearest
    scanned ancestor is used instead, logged at warning with the commit chosen and
    its distance. Only an unreachable ancestor now fails the run.
    
    Both bounds are fixed and neither costs an extra request: the listing is fetched
    once, and the walk stops at a set depth. Following first parents keeps a merge
    commit from contributing everything merged into it, and a shallow checkout
    simply narrows the search rather than breaking it.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix: harden diff baseline resolution
    
    ---------
    
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
    lelia and claude authored Sep 15, 2026
    Configuration menu
    Copy the full SHA
    88408dc View commit details
    Browse the repository at this point in the history
  3. Preserve pull request context, full-scan SCM branch pipelines, and ga…

    …te ignore commands (#302)
    
    * feat(output): show patched versions in security findings
    
    * feat(ci): preserve pull request context in scan metadata
    
    * chore(release): bump version to 2.9.0
    
    2.8.0 and 2.8.1 shipped from main while this branch was open, so the original
    2.8.0 bump here is dead. This branch changes the behavior of existing flags
    rather than only fixing them -- --pr-number gains auto-detection, --scm
    github|gitlab implies --integration, and SCM branch pipelines switch from diff
    scans to full scans and stop returning a blocking exit code -- so it takes the
    minor bump per the repo's semver standard, not a patch.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * refactor: share one git remote parser between Buildkite consumers
    
    The GitHub comment adapter and pull request link construction each parsed
    BUILDKITE_REPO independently. Consolidate on socketsecurity.core.git_remote,
    which also reports the remote host (needed for self-hosted GitHub Enterprise
    and GitLab) and preserves nested GitLab subgroup paths.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(ci): apply the pull request link to an already-compared scan pair
    
    external_href is only honored while a diff scan is being created, so a
    re-run over the same before/after pair left the Dashboard report with no
    link back to its pull request. Send on_duplicate=update alongside it, which
    applies the link to the existing diff scan and answers 200 with the same
    envelope as a create.
    
    The 409-and-resolve path is retained for runs with no pull request context
    and for deployments that predate on_duplicate=update.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(comments): make per-alert ignores round trip
    
    * fix(comments): preserve dependency change types
    
    * fix(ci): use full scans outside pull requests
    
    * docs: update release notes for comment fixes
    
    * fix(ci): restrict SCM diffs to pull requests
    
    * fix(scans): keep the package list on full scans
    
    create_full_scan_with_report_url only fetched SBOM data when an alert-bearing
    output format was enabled, so --generate-license and --legal-format fossa saw an
    empty diff.packages and wrote an attribution file with zero packages. That is the
    list they enumerate, as _requires_unchanged_artifacts already documents for the
    comparison path.
    
    Fetch the SBOM for them too, and enrich it through the PURL endpoint the way the
    comparison path does. The full scan's package map is keyed by artifact id while
    get_license_text_via_purl keys off ecosystem/name@version, so pass a purl-keyed
    view over the same Package objects.
    
    Alert consolidation stays behind its own gate, so an alert-only run does not pay
    for the license lookup and a license-only run does not build an alert list.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(ci): keep branch pipelines out of pull request handling
    
    Two ways an SCM branch build could still be treated like a pull request:
    
    Buildkite always sets BUILDKITE_PULL_REQUEST, to the string "false" on a branch
    build, so the documented --pr-number "$BUILDKITE_PULL_REQUEST" form delivers a
    truthy non-numeric value. resolve_pull_request_context read it as no PR but only
    wrote the normalized number back when one was found, so GithubConfig still saw
    "false", check_event_type returned "diff" for a push, and comment lookups went to
    issues/false/comments. Canonicalize config.pr_number before any adapter reads it.
    
    A branch run creating a full scan then blocked on diff.new_alerts, which a full
    scan cannot fill meaningfully: empty with no alert-bearing output format enabled,
    and every alert in the scan rather than the newly introduced ones with one. The
    exit code therefore depended on which output format was requested. Treat these
    runs the way a run with no supported manifest files is already treated and skip
    blocking, leaving pull request pipelines to enforce policy.
    
    Move the scan-type decision into create_scm_scan, which returns the diff and
    whether it came from a comparison, so the branch is exercised by tests rather
    than only its predicate. Document both the scan-type table and the blocking
    consequence in the CI/CD guide.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(comments): stop reading an npm scope as an ecosystem
    
    Ignore matching strips the ecosystem off a command so an ecosystem-qualified
    reply still matches the bare package name parsed out of a start-socket-alert
    marker. It stripped any leading path segment, and a scope sits in the same
    position, so "ignore @types/node@*" also suppressed alerts for a package named
    node. Only strip a leading segment that cannot be a scope.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(comments): keep the diff badge where artwork exists
    
    Labelling every dependency overview row with bold text dropped the badge from
    added rows, which is the only category the overview rendered before. The badge
    host publishes diff-added.svg and diff-updated.svg but nothing for removed or
    replaced, so look the badge up per change type and fall back to the text label
    only where there is no image to render.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * refactor(config): scope the config-file defaults dict to its block
    
    normalized_defaults has no reader outside the branch that fills it.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * docs: correct the release notes for branch pipeline scans
    
    The entry still described the intermediate behavior where explicit diff flags
    opted a non-PR run into comparison mode; the detected event type has been
    authoritative since that was reverted. Record the blocking and license
    consequences alongside it, plus the ignore and overview fixes.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(comments): stop legacy comment updates crashing on scoped names
    
    process_original_security_comment split the package cell on every "@", so a
    scoped name carrying its own "@" unpacked into three values and raised an
    uncaught ValueError. Same bug class this branch already fixed one function over
    in process_updated_security_comment, just left in its sibling.
    
    Split from the right, and pass the ecosystem through as pkg_type rather than
    pre-concatenating it onto the package name. That makes the two comment formats
    agree: both now accept an ignore command for a scoped package in either the
    ecosystem-qualified or the bare form, where the legacy path previously matched
    only the qualified one.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(comments): require write access to ignore an alert
    
    An @SocketSecurity ignore command suppresses a security finding, but the CLI
    honored one from any commenter. Comment.author_association was carried on the
    dataclass and never read, so nothing on the path from comment to suppressed alert
    asked whether the author could push to the repository. A drive-by ignore-all on an
    open pull request silenced every finding on it.
    
    Gate the ignore bucket in check_for_socket_comments, the one place every consumer
    goes through. A rejected command is logged with its author and is also absent from
    the ignore telemetry, which should record what was acted on.
    
    GitHub returns author_association with every comment, so the check is free and
    definitive: OWNER, MEMBER and COLLABORATOR only. GitLab notes carry no equivalent,
    so project membership is read once per run, and only when an ignore command is
    actually present. members/all is used rather than a per-user lookup because it
    answers non-membership with a 200 and an absent id -- CliClient collapses every
    HTTP error into APIFailure without a status code, so a per-user 404, exactly the
    outsider case, would be indistinguishable from a token that cannot read the
    endpoint and would have to fail open.
    
    When membership genuinely cannot be read -- a CI_JOB_TOKEN typically cannot --
    the command is honored and a warning names the author, so this does not silently
    break pipelines already relying on ignore commands. Documented alongside the
    token requirement to get enforcement.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(ci): validate CI-supplied server URLs before building a link
    
    GITHUB_SERVER_URL and CI_SERVER_URL were composed into the pull request link
    verbatim, while the sibling repository URLs read from the same environment
    already went through a scheme/netloc check. The result is sent to the API as a
    diff scan's external_href, so route all of them through one validator.
    
    Standard runners set these themselves, so this is defense in depth rather than a
    live hole. An unusable value now falls back to github.com for GitHub; GitLab has
    no public default host, so the link is dropped and the scan keeps its number.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * docs: correct the add_purl_capabilities docstring
    
    The loop covers updated_packages as well as new_packages; the docstring still
    described only the latter.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * docs: record the review fixes in the 2.9.0 release notes
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * docs: rewrite branch comments for the reader, not the author
    
    Sweep of every comment this branch adds, against the fourth-wall skill:
    
    - A test docstring stated the scan type "(since 2.8.0)", which was already
      wrong after the renumber to 2.9.0 and would rot again on the next one. Version
      stamps in comments describe a debut rather than the behavior.
    - Two docstrings narrated the failure the old parser produced instead of the
      invariant that makes rsplit correct. A scoped name carrying its own "@" is the
      whole reason; the traceback it used to raise is not.
    - The "do NOT use on_duplicate=redirect" landmine was explained twice, in full,
      at both call sites. Kept at the 409 fallback, where the temptation to add it
      lives; the create site now just says what update does.
    - A test section header justified its own design to a reviewer ("swapping the
      call back ... fails them"). Restated as what the test actually pins.
    - "out of this branch" in the remote-URL regex reads as a git branch in this
      repo; it means the regex case.
    
    642 passed, ruff clean.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(comments): parse legacy alert rows defensively
    
    Each row of the legacy comment table was unpacked through four consecutive
    splits with no bounds checks: five cells, then the markdown link, then the
    ecosystem, then the version. The row comes back from the provider's API, so a
    cell carrying an extra "|", a package cell that is not a link, or a name with no
    version raised out of the comment rewrite and ended the run before it reported
    status. A scoped package name in Socket's own table reached the same place with
    nobody doing anything unusual.
    
    parse_alert_table_row returns None instead of raising for any row it cannot
    read, and an unreadable row keeps its alert reported -- the safe direction, since
    a row that cannot be parsed cannot be evaluated against the ignore commands
    either.
    
    Also pins change-type preservation against the real artifact conversion rather
    than a stubbed field. The existing test assigned diffType by hand, so it would
    have passed whether or not the conversion populated it; the new one runs real
    DiffArtifact objects through both response shapes, and fails if the field is
    dropped.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * feat(comments): add --ignore-authorization
    
    The write-access gate had no escape hatch, and its GitLab behavior when project
    membership cannot be read -- honor the command with a warning -- was the one
    deliberate weakness in it. Both are now a choice:
    
      enforce (default)  require write access; honor with a warning where the
                         provider cannot report it
      strict             reject in that case instead
      off                perform no check
    
    enforce closes the hole wherever the provider can answer without breaking a
    pipeline whose token cannot read membership, which is why it is the default.
    strict closes it everywhere and will fail those pipelines. off restores the prior
    behavior for anyone who needs comment-driven ignores from unverified authors.
    
    Threaded through the adapter constructors as a keyword argument with a default, so
    existing call sites keep working. With off the predicate is never handed to
    check_for_socket_comments at all, so nothing is filtered and no rejection is
    logged, rather than a gate that silently approves everything.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(comments): escape repository-derived values when rendering comments
    
    Manifest paths and sources are file paths inside the scanned repository, so
    anyone who can open a pull request controls them: a directory named with link or
    tag syntax, holding a manifest, put that markup into a comment posted by a trusted
    integration. Alert text comes from the API. Neither is markup the CLI authored, so
    both are escaped where they are interpolated -- text nodes with html.escape,
    href and src with quotes escaped too, since an unescaped quote closes the
    attribute and everything after it reads as more attributes.
    
    The alert markers are the exception: they are read back verbatim when a comment is
    rewritten, so they cannot be escaped without breaking the ignore round trip. They
    instead lose only the ability to terminate the comment early.
    
    plain and raw styles are untouched. Slack, Jira and the console do not render
    HTML, and escaping there would show entities to a human.
    
    Round-trip tests render a comment with each hostile path and feed it back through
    the parser, because the renderer and the parser are two halves of one loop: an
    escaping choice the parser cannot read would silently stop ignores working.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(gitlab): make the authentication fallback actually run
    
    _get_auth_headers guesses between Bearer and PRIVATE-TOKEN from the shape of the
    token, and retries once under the other scheme on a 401 so a wrong guess does not
    fail the run. That retry has never executed.
    
    Three things had to line up and none of them did:
    
      - The retry caught requests.exceptions.HTTPError, but CliClient translates every
        requests error into APIFailure before it gets there.
      - CliClient discarded the HTTP status, so even a caught failure could not be
        identified as a 401. is_transient_error was equally blind for the same reason.
      - There are two APIFailure classes -- the CLI's own and the SDK's -- and they
        were independent Exception subclasses. CliClient raises the CLI's; every
        handler in socketsecurity.core imports the SDK's. None of those eight handlers
        has ever caught a CliClient failure.
    
    The CLI's APIFailure now subclasses the SDK's, so a handler written against either
    catches both, and the status code travels with the exception.
    
    The two tests covering the fallback were skipped rather than fixed, with a reason
    that no longer described the failure -- the constructor they blamed is used by the
    two passing tests in the same file. They now drive the exception the way CliClient
    actually raises it, and fail if any of the three links above is broken again.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    
    * fix(review): address authorization and full-scan findings
    
    * fix(comments): close ignore authorization gaps
    
    ---------
    
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
    lelia and claude authored Sep 15, 2026
    Configuration menu
    Copy the full SHA
    a96f054 View commit details
    Browse the repository at this point in the history

Commits on Sep 16, 2026

  1. Bump pinned @coana-tech/cli to 15.10.43 (#356)

    Co-authored-by: socket-pr-bot[bot] <294242679+socket-pr-bot[bot]@users.noreply.github.com>
    socket-pr-bot[bot] authored Sep 16, 2026
    Configuration menu
    Copy the full SHA
    5384fcd View commit details
    Browse the repository at this point in the history

Commits on Sep 17, 2026

  1. Bump pinned @coana-tech/cli to 15.10.44 (#357)

    Co-authored-by: socket-pr-bot[bot] <294242679+socket-pr-bot[bot]@users.noreply.github.com>
    socket-pr-bot[bot] authored Sep 17, 2026
    Configuration menu
    Copy the full SHA
    5c1674a View commit details
    Browse the repository at this point in the history
  2. Bump pinned @coana-tech/cli to 15.10.45 (#358)

    Co-authored-by: socket-pr-bot[bot] <294242679+socket-pr-bot[bot]@users.noreply.github.com>
    socket-pr-bot[bot] authored Sep 17, 2026
    Configuration menu
    Copy the full SHA
    ad62842 View commit details
    Browse the repository at this point in the history
Loading