Skip to content

Default the scancode licence stage to off - #296

Merged
haksungjang merged 3 commits into
mainfrom
scancode-default-off
Sep 3, 2026
Merged

Default the scancode licence stage to off#296
haksungjang merged 3 commits into
mainfrom
scancode-default-off

Conversation

@haksungjang

@haksungjang haksungjang commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Problem

scancode detects licences in first-party source: code the organisation wrote. Dependency licences come declared from cdxgen and never go through this stage, and neither path feeds vulnerability matching. A deployment scanning for CVEs therefore pays for the stage on every scan and reads none of its output.

The cost is per-scan wall clock: the stage reads every eligible file in the tree. That is why it already carries its own timeout (default 600s), its own file ceiling, and its own detection cap, and why the public demo has always run with it off.

Change

SCANCODE_ENABLED now defaults to false and fails closed: only true / 1 / yes enable it, anything else including typos reads as off. That is the same shape as the neighbouring scanoss_enabled, so the two switches now read the same way.

This reverses the previous default-on / fail-open reasoning, which was that scancode is a pure-local pass with no egress and so costs nothing worth gating. Local is not the same as free.

Turning the stage off was already a supported, non-fatal path: run_scancode short-circuits with ScancodeDisabled and the pipeline continues on declared licences. Nothing about the off-behaviour changes here; what changes is which deployments get the stage without asking for it.

A correction, recorded

The first version of this PR justified the change with a disk figure: 2.99 GB of cache attributed to scancode's rule index on a 2,080-repository corpus run. That attribution was wrong. The growth was pip's download cache. Both live under ~/.cache; scancode's own subdirectory measured 0 bytes, and the directory kept growing after this stage was disabled, which is what exposed the mistake. The real defect is fixed in #302.

The reason to default this off never rested on that figure and is unchanged.

Upgrade note

A deployment that reads detected first-party licences must now set SCANCODE_ENABLED=true explicitly. This is called out in the accessor docstring and in .env.example, alongside why you would want it: detected first-party licences are how vendored or pasted third-party code gets found, and dependency metadata never shows it. Licence-compliance deployments should turn it on.

Test plan

  • tests/unit/test_scancode_config.py rewritten for the new default: off by default, true/1/yes enable, and on / enable / junk all read as off (those two are asserted deliberately, since they look like intent to enable and are not).
  • tests/unit/integrations/test_scancode.py gains an autouse fixture enabling the stage. Those tests are about what the adapter does when it runs; the off-path is covered in the config test.
  • Full pytest tests/unit (6,800+ tests). The only remaining failures are 2 pre-existing ones in test_admin_team_service.py, verified to reproduce unchanged with this branch stashed.
  • The demo-sandbox guard still holds: it asserts the stage is off, which the new default satisfies without configuration.
  • mypy . clean over 823 files; ruff check . clean; em-dash lint clean.

scancode detects licences in first-party source. Dependency licences come
declared from cdxgen and do not go through it, and neither path feeds
vulnerability matching, so a deployment scanning for CVEs paid for the
stage on every scan and read none of its output.

The cost is not marginal. On a 2,080-repository corpus run its rule index
reached 2.99 GB in one worker overnight, which was that worker's entire
toolchain cache and enough to take a 26 GB root partition to 100%.

SCANCODE_ENABLED now defaults to false and fails closed, matching
scanoss_enabled: only true / 1 / yes enable it. Turning it off was
already a supported non-fatal skip, so the pipeline behaviour when off is
unchanged; what changes is which deployments get it without asking.

Upgrade note: licence-compliance deployments must now set it explicitly.
Detected first-party licences are how vendored or pasted third-party code
is found, and dependency metadata never shows it.
The 2.99 GB attributed to scancode's rule index was pip's download
cache. Both live under .cache, and scancode's own subdirectory measured
0 bytes; the disk growth continued with the stage disabled, which is
what exposed the misattribution. That defect is fixed separately.

The reason to default this off is unchanged and does not rest on the
disk claim: the stage reads every eligible file in the tree to produce
detected first-party licences, which do not feed vulnerability matching.
The cost cited is now the per-scan wall clock the stage's own timeout,
file ceiling and detection cap already exist to bound.
The test asserts a scancode_result artifact is persisted, which the
stage only produces when it runs. With the default now off it has to
request the stage explicitly. The off-path stays covered by the config
unit tests.
@haksungjang
haksungjang merged commit c1884cc into main Sep 3, 2026
24 checks passed
@haksungjang
haksungjang deleted the scancode-default-off branch September 3, 2026 05:31
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