-
Notifications
You must be signed in to change notification settings - Fork 0
fix(ci): decouple dashboard/report smoke from stand-only sts_audit #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+71
−6
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| { | ||
| "_note": "GOLDEN smoke fixture for the dashboard/report CI (viz/build_dashboard.py + report.cli). Fully SYNTHETIC — invented module/file/handler names, not from any real audited project. Its only job is to exercise the render/export code paths (every tool, tier, source family, category, and OWN leak-shape) so CI catches Python/JS-template regressions without depending on the stand-only sts_audit corpus. Keep it small and stable.", | ||
| "coverage": { | ||
| "tools": ["own-check", "roslyn", "codeql", "infersharp"], | ||
| "total": 14, | ||
| "kept": 14, | ||
| "suppressed": 0, | ||
| "suppressed_by": {}, | ||
| "analysis_skipped": 0, | ||
| "analysis_skipped_by": {}, | ||
| "by_category": {"1": 3, "2": 2, "3": 2, "4": 3, "5": 1, "6": 2, "7": 1}, | ||
| "uncategorized_rules": {} | ||
| }, | ||
| "findings": [ | ||
| {"tool": "own-check", "path": "Acme.Portfolio/ViewModels/PortfolioViewModel.cs", "line": 42, "rule": "OWN001", "category": 2, "category_name": "subscription-leak", "resource": "subscription token", "suppressed": false, "suppress_reason": "", "message": "event 'quotes.Updated' is subscribed (handler '(s, e) => Refresh()') but never unsubscribed; its source is an injected dependency whose lifetime is unknown, so it may outlive and keep 'PortfolioViewModel' alive (possible leak) [resource: subscription token]"}, | ||
| {"tool": "own-check", "path": "Acme.Portfolio/ViewModels/PortfolioViewModel.cs", "line": 58, "rule": "OWN001", "category": 2, "category_name": "subscription-leak", "resource": "subscription token", "suppressed": false, "suppress_reason": "", "message": "event 'service.Ticked' is subscribed (handler 'OnTicked') but never unsubscribed; its source outlives the view model, so it may keep 'PortfolioViewModel' alive (possible leak) [resource: subscription token]"}, | ||
| {"tool": "own-check", "path": "Acme.Portfolio/Data/PortfolioRepository.cs", "line": 19, "rule": "OWN020", "category": 1, "category_name": "idisposable-leak", "resource": "connection", "suppressed": false, "suppress_reason": "", "message": "field '_conn' (DbConnection) is created but never disposed; it holds an unmanaged handle for the lifetime of 'PortfolioRepository' (possible leak) [resource: connection]"}, | ||
| {"tool": "own-check", "path": "Acme.Market/Services/QuoteFeed.cs", "line": 77, "rule": "OWN021", "category": 1, "category_name": "idisposable-leak", "resource": "stream", "suppressed": false, "suppress_reason": "", "message": "local 'buffer' (MemoryStream) is created but never disposed; wrap it in a using statement (possible leak) [resource: stream]"}, | ||
| {"tool": "own-check", "path": "Acme.Portfolio/Reports/PdfExporter.cs", "line": 61, "rule": "OWN-REGION", "category": 7, "category_name": "region-escape", "resource": "region handle", "suppressed": false, "suppress_reason": "", "message": "a rented buffer escapes its region via the returned closure; ownership is ambiguous and it may never be released (possible leak) [resource: region handle]"}, | ||
| {"tool": "roslyn", "path": "Acme.Portfolio/ViewModels/PortfolioViewModel.cs", "line": 33, "rule": "INPC020", "category": 3, "category_name": "inpc-correctness", "resource": "", "suppressed": false, "suppress_reason": "", "message": "prefer a nameof() expression over the string literal for the raised property name"}, | ||
| {"tool": "roslyn", "path": "Acme.Portfolio/ViewModels/PositionViewModel.cs", "line": 14, "rule": "INPC003", "category": 3, "category_name": "inpc-correctness", "resource": "", "suppressed": false, "suppress_reason": "", "message": "notify when the 'Quantity' property value changes"}, | ||
| {"tool": "roslyn", "path": "Acme.Market/Services/QuoteFeed.cs", "line": 90, "rule": "MA0006", "category": 4, "category_name": "general-quality", "resource": "", "suppressed": false, "suppress_reason": "", "message": "use String.Equals instead of the equality operator for culture-aware comparison"}, | ||
| {"tool": "roslyn", "path": "Acme.UI/Controls/GaugeControl.cs", "line": 120, "rule": "WPF0041", "category": 5, "category_name": "wpf-freezable", "resource": "", "suppressed": false, "suppress_reason": "", "message": "set the DataContext in the constructor rather than in a loaded handler"}, | ||
| {"tool": "roslyn", "path": "Acme.Portfolio/Data/PortfolioRepository.cs", "line": 48, "rule": "CA2000", "category": 1, "category_name": "idisposable-leak", "resource": "", "suppressed": false, "suppress_reason": "", "message": "call System.IDisposable.Dispose on the object before all references to it are out of scope"}, | ||
| {"tool": "roslyn", "path": "Acme.UI/Controls/GaugeControl.cs", "line": 7, "rule": "RCS1037", "category": 4, "category_name": "general-quality", "resource": "", "suppressed": false, "suppress_reason": "", "message": "remove trailing white-space"}, | ||
| {"tool": "roslyn", "path": "Acme.Portfolio/Reports/PdfExporter.cs", "line": 25, "rule": "RCS1090", "category": 6, "category_name": "architecture", "resource": "", "suppressed": false, "suppress_reason": "", "message": "add a ConfigureAwait(false) call to the awaited task"}, | ||
| {"tool": "codeql", "path": "Acme.Market/Services/QuoteFeed.cs", "line": 132, "rule": "cs/dereferenced-value-may-be-null", "category": 6, "category_name": "architecture", "resource": "", "suppressed": false, "suppress_reason": "", "message": "this expression may be null at this access and would raise a NullReferenceException"}, | ||
| {"tool": "infersharp", "path": "Acme.Portfolio/Reports/PdfExporter.cs", "line": 88, "rule": "NULL_DEREFERENCE", "category": 4, "category_name": "general-quality", "resource": "", "suppressed": false, "suppress_reason": "", "message": "object returned by the factory could be null and is dereferenced without a guard"} | ||
| ] | ||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Acme (synthetic) — health report | ||
|
|
||
| > GOLDEN smoke fixture for `viz/build_dashboard.py`. Fully synthetic; not a real | ||
| > project. Mirrors the shape `build_dashboard.py` parses (the summary line below and | ||
| > the module pain table) so the dashboard renders in CI without the stand-only | ||
| > `sts_audit` corpus. Numbers are illustrative, not a real audit. | ||
|
|
||
| ## Summary | ||
|
|
||
| **14 findings** (5 high-confidence, 9 candidate). High-confidence = flagged by ≥2 independent tools at the same spot. | ||
|
|
||
| ## Module pain | ||
|
|
||
| | module | pain | findings | high-conf | top category | | ||
| |---|---:|---:|---:|---| | ||
| | `Acme.Portfolio` | 128.0 | 6 | 3 | subscription-leak | | ||
| | `Acme.Portfolio/Reports` | 74.0 | 3 | 1 | architecture | | ||
| | `Acme.Market` | 63.0 | 3 | 1 | general-quality | | ||
| | `Acme.UI` | 21.0 | 2 | 0 | wpf-freezable | |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the caller supplies the new fixture path, treating missing inputs as success makes the dashboard smoke a no-op:
report.clionly requiresfindings.json, so ifviz/fixtures/health-report.mdis deleted/renamed or the CI path points at an empty directory, the workflow'spython3 viz/build_dashboard.py viz/fixturesstill exits 0 here without rendering the dashboard. Limit the clean skip to the default emptyartifacts/case, or make CI assert the fixture files exist before relying on the smoke.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch — fixed in
78132ca(your first option). The clean skip now applies only to the implicit defaultartifacts/(empty until a stand run populates it). An explicitly-supplied dir missingfindings.json/health-report.mdis now a hard error (argparseexit 2), so CI'sbuild_dashboard.py viz/fixturesfails loudly if the fixture is ever deleted/renamed — no more silent no-op.Verified: explicit valid → render (exit 0); default empty
artifacts/→ skip (exit 0); explicit dir missing a file / nonexistent → exit 2.Generated by Claude Code