Three regressions surfaced after #5604 landed. All addressed here with
matching pytest coverage.
1. Default mode no longer blocks on `unsupported-lockfile-version`. A
lockfile downgraded to v1 (or bumped to an unsupported future
version) silently passes default CI because the auditor's structural
walk only runs on v2/v3, so `blocked-known-malicious` /
`known-ioc-string` findings cannot be produced. v1 downgrade is a
documented supply-chain attack shape; restoring it to BLOCKING_KINDS.
2. `UNSLOTH_LOCKFILE_AUDIT_SKIP` warnings interpolated the raw env var
value into `:⚠️:` workflow commands without `_gha_escape()`,
so a value containing `\n::error::...` was emitted as a second
physical workflow-command line (GH Actions parses workflow commands
per physical line). Routing both branches through `_gha_escape()`
collapses any control char onto a single annotation line.
3. The two workflows that consume `studio/package-lock.json` --
`studio-tauri-smoke.yml` and `release-desktop.yml` -- did not invoke
`scripts/lockfile_supply_chain_audit.py` before their `npm install`
steps. Lifecycle scripts in a compromised lockfile would run before
the audit could refuse the lockfile, defeating the script's
"pre-install" guarantee. `release-desktop.yml` additionally has
`contents: write`, so the gap had real publish-attacker blast
radius. Both workflows now run the audit before any `npm install`
or `npm ci`.
Tests
-----
- test_unsupported_lockfile_version_blocks_default: v1 lockfile must
exit 1 in default mode.
- test_blocking_kinds_contains_unsupported_lockfile_version: direct
module-level pin against future regressions.
- test_skip_env_warning_escapes_workflow_command_injection: both
skip-env branches must escape `\n` / `%` so no injected physical
workflow-command line is produced.
- test_audit_runs_before_npm_install_in_consumer_workflows: regex
ordering check on the `run:` lines in the two consumer workflows so
a future reorder cannot silently bring back the pre-install gap.
16/16 pytest pass; default-mode audit still rc=0 on real lockfiles.