fix(ci+sarif): eliminate self-hosting false-positive security alerts#15
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
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 nosrc/prefix, socore/run.py→core.run. But every intra-package import uses the fully qualified path:from wardline.core.run import ...→ modulewardline.core.run. That name was never inproject_modules, so WLN-ENGINE-UNKNOWN-IMPORT fired for every single import across the codebase.Fix: Change CI scan root to
src/. Nowwardline/core/run.py→wardline.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-RESOLUTIONfindings 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 — butbuild_sarif()was serializing all findings regardless ofKind, producinglevel: noteSARIF results → GitHub alerts.Fix: Exclude
Kind.METRICfindings frombuild_sarif(). The full picture (including metrics) remains available in the JSONL sink.Kind.DEFECTandKind.FACTfindings (including the actionableWLN-L3-MONOTONICITY-VIOLATION) are unaffected.Verification
Files changed
.github/workflows/ci.yml:src/wardline→src/in the scan commandsrc/wardline/core/sarif.py: filterKind.METRICfindings before serializingtests/unit/core/test_sarif.py: addtest_metric_findings_excluded_from_sarif