Skip to content

fix(ci+sarif): eliminate self-hosting false-positive security alerts#15

Merged
tachyon-beep merged 14 commits into
mainfrom
fix/self-hosting-scan-alerts
Jun 1, 2026
Merged

fix(ci+sarif): eliminate self-hosting false-positive security alerts#15
tachyon-beep merged 14 commits into
mainfrom
fix/self-hosting-scan-alerts

Conversation

@tachyon-beep

Copy link
Copy Markdown
Collaborator

Problem

~200 GitHub Code Scanning alerts were being generated by Wardline's own self-hosting dogfood scan in CI. These were false positives caused by two separate bugs.

Root cause 1: Wrong scan root in CI (~140 alerts)

CI was running wardline scan src/wardline. With that root, module_dotted_name() strips no src/ prefix, so core/run.pycore.run. But every intra-package import uses the fully qualified path: from wardline.core.run import ... → module wardline.core.run. That name was never in project_modules, so WLN-ENGINE-UNKNOWN-IMPORT fired for every single import across the codebase.

Fix: Change CI scan root to src/. Now wardline/core/run.pywardline.core.run, which matches imports exactly. Zero UNKNOWN-IMPORT findings after this change.

Root cause 2: Kind.METRIC engine telemetry in SARIF (~60 alerts)

After fixing the scan root, WLN-L3-LOW-RESOLUTION findings remained. These are call-graph resolution quality statistics (e.g., "80% of calls in this function are to external libs wardline can't resolve"). They're engine telemetry — not actionable code issues — but build_sarif() was serializing all findings regardless of Kind, producing level: note SARIF results → GitHub alerts.

Fix: Exclude Kind.METRIC findings from build_sarif(). The full picture (including metrics) remains available in the JSONL sink. Kind.DEFECT and Kind.FACT findings (including the actionable WLN-L3-MONOTONICITY-VIOLATION) are unaffected.

Verification

wardline scan src/ --format sarif --output /tmp/check.sarif
# SARIF results: 0
  • 1001 tests pass, 2 deselected (network/clarion e2e, as expected)
  • Ruff clean
  • Mypy clean

Files changed

  • .github/workflows/ci.yml: src/wardlinesrc/ in the scan command
  • src/wardline/core/sarif.py: filter Kind.METRIC findings before serializing
  • tests/unit/core/test_sarif.py: add test_metric_findings_excluded_from_sarif

John Morrissey and others added 14 commits June 1, 2026 16:39
Appends §8 to wardline-030 spec with all findings from the
five-panel review (Architecture Critic, Systems Thinker,
Python Engineer, Static Analysis Engineer, Quality Engineer).

Critical blockers (must resolve in spec before coding):
- BLOCKER-1: complete write-site list (8 missed sites)
- BLOCKER-2: name-copy propagation decision required
- BLOCKER-3: tie-break rule corrected to match consumer logic

Important (resolve before merge):
- RESOLVE-4: _handle_augassign exact callee rule
- RESOLVE-5: _handle_unpack element-wise vs whole-RHS semantics
- RESOLVE-6: structural recommendation (_L2State dataclass)
- RESOLVE-7: source_boundary_qualname is a user-visible API change
- RESOLVE-8: match capture pattern callee inheritance
- RESOLVE-9: walrus threading depth and analyzer.py isolation

Required tests (9 additional, 5 critical):
- TEST-1..5 critical: loop back-edge, tie-break, mixed paths,
  invariance corpus definition, negative boundary test
- TEST-6..9 important: unpack, augassign, walrus, obj.attr

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Covers the use/develop documentation split, a filigree-class README,
full uv toolchain parity, CI hardening (3.12/3.13 matrix + 90% coverage
floor), Makefile, pre-commit, expanded CONTRIBUTING, and a ROADMAP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Edits §§3–7 to address every item from the §8 panel review:

BLOCKER-1 (write-site list incomplete):
- §4 now enumerates all 14 write sites: _seed_parameters, _handle_assign,
  AnnAssign, _assign_target (for/match/nested-unpack), _handle_unpack,
  _handle_augassign, NamedExpr walrus, _walk_exprs_for_walrus, _handle_with,
  _taint_container_base, except-as binding, plus 5 merge sites.
- _assign_target callee rules table added (for vs match vs nested unpack).

BLOCKER-2 (name-copy propagation):
- §3 chooses Option A: Name-copy propagates provenance (y=x sets
  callees[y]=callees.get(x)). Attribution rule table added.
- Clarifies 'single-hop' boundary applies to compute_return_callee
  lookup depth, not alias copy count.

BLOCKER-3 (tie-break rule):
- §3 merge rule corrected: first source-order worst-rank branch with
  non-None callee; None only when every worst-rank branch is None.
  Matches consumer logic exactly.

RESOLVE-4 (_handle_augassign exact rule): §4 specifies winning-rank
determines callee; equal-rank keeps existing (left-wins).

RESOLVE-5 (_handle_unpack callee semantics): §4 specifies element-wise
rule for arity-matched literals; whole-RHS attribution otherwise;
Starred targets always None.

RESOLVE-6 (_L2State structure): §3 adopts _L2State as the design
choice. compute_variable_taints returns _L2State; all walkers take it.

RESOLVE-7 (source_boundary_qualname API change): §4 downstream note
and §6 both now call this a user-visible contract change with explicit
negative-case behaviour documented.

RESOLVE-8 (match capture callee inheritance): covered in §4
_assign_target table.

RESOLVE-9 (walrus threading depth + analyzer.py isolation): §4
explicitly calls out _walk_exprs_for_walrus / _resolve_comprehension
threading and marks the analyzer.py copy as a code change required.

§5 test list expanded from 4 to 12 tests, with code sketches for all
new cases (loop back-edge, tie-break, mixed paths, alias, negative
source_boundary, unpack, augassign, walrus, fire-set corpus definition).

§6 adds source_boundary_qualname contract change and analyzer.py
isolation bullets.

§7 effort estimate updated to Medium (was Small-Medium); 14 write sites
+ _L2State + return-type change + 12 tests.

§8 status updated to RESOLVED.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two root causes behind the ~200 GitHub Code Scanning alerts produced by
the wardline self-hosting dogfood scan:

1. Wrong scan root in CI (src/wardline → src/)
   - CI ran: wardline scan src/wardline
   - module_dotted_name() with root=src/wardline strips no src/ prefix,
     so 'core/run.py' → 'core.run'. But every intra-package import is
     'from wardline.core.run import ...' which maps to 'wardline.core.run'.
   - 'wardline.core.run' ∉ project_modules → WLN-ENGINE-UNKNOWN-IMPORT
     fires for every single import in every file. (~135 alerts)
   - Fix: scan src/ so relpath is 'wardline/core/run.py' → 'wardline.core.run'
     which now matches the import names. Zero UNKNOWN-IMPORT after fix.
   - Also eliminates WLN-ENGINE-NO-MODULE (the package __init__.py was
     mapping to None with the wrong root).

2. Kind.METRIC findings leaking into SARIF output
   - After fixing the scan root, WLN-L3-LOW-RESOLUTION findings remain.
     These are engine telemetry (call graph resolution quality stats for
     functions that call external libraries like click, pyyaml, etc.) —
     not actionable code issues.
   - build_sarif() was serializing ALL findings regardless of Kind, causing
     ~60 'note'-level SARIF results → GitHub Code Scanning alerts.
   - Fix: exclude Kind.METRIC findings in build_sarif(). JSONL output
     retains the full picture including metrics.
   - Kind.DEFECT and Kind.FACT remain in SARIF (including
     WLN-L3-MONOTONICITY-VIOLATION which is Kind.DEFECT and IS actionable).

Verified: wardline scan src/ --format sarif produces 0 SARIF results.
All 1001 tests pass. Ruff and mypy clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 1, 2026 07:06
@tachyon-beep
tachyon-beep merged commit c48b7ae into main Jun 1, 2026
7 of 9 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@tachyon-beep
tachyon-beep deleted the fix/self-hosting-scan-alerts branch June 22, 2026 20:52
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.

2 participants