ci: shard zig-tsan + zig-coverage 5-way; fix TSan never actually running#5
Merged
ci: shard zig-tsan + zig-coverage 5-way; fix TSan never actually running#5
Conversation
The single zig-tsan and zig-coverage CI jobs were hitting their timeout ceilings (60min and 30min respectively). While verifying the sharding fix, found that the TSan job was never actually instrumenting tests -- `zig build test -Dsanitize-thread` flowed the flag through to unit_tests built in stage2 + Debug, which silently drops the TSan runtime. The actually-instrumented path (`test-tsan` step, LLVM + sanitize_thread) was never invoked from CI. Changes: - build.zig: add `-Dshard-index` / `-Dshard-count` options. Round-robin filter applied to both `test_step` (used by coverage) and `test_tsan_step` (used by the new TSan job). Defaults (1, 0) preserve unsharded local behavior. - build.zig: switch TSan optimize from ReleaseSafe to Debug. TSan needs LLVM backend, not ReleaseSafe specifically -- the original comment conflated the two. Debug + LLVM + TSan compiles ~4x faster (3s vs 15s/test) and yields more instrumentation symbols than ReleaseSafe (which optimized some away). - ci.yml: zig-tsan switched from `zig build test -Dsanitize-thread` to `zig build test-tsan` so real TSan runs. Matrix-sharded 5-way; per- shard timeout 30min (measured ~7s locally for shard 0 with 9 tests). - ci.yml: zig-coverage matrix-sharded 5-way. Each shard uploads its own cobertura.xml; Codecov server-side merges via shared `flags: zig`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #5 +/- ##
==========================================
- Coverage 83.94% 83.70% -0.25%
==========================================
Files 51 58 +7
Lines 19505 19850 +345
Branches 8340 8340
==========================================
+ Hits 16374 16615 +241
- Misses 3131 3235 +104
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
cuzzo
added a commit
that referenced
this pull request
May 7, 2026
Self-host prep tracker task #10 (P1, Sorbet/RBS gradual typing). Adds: - Gemfile gems: sorbet, sorbet-runtime, tapioca (development group) - sorbet/config: --dir . with vendor/, zig*/, spec/, transpile-tests/, examples/, benchmarks/, tmp/, docs/ ignored - sorbet/rbi/clear-stubs.rbi: hand-written Token stub to silence the one default-typed-false name-resolution false positive in parser.rb:63 (Sorbet suggested Socket) - .gitignore allow-list entry for /sorbet/ - docs/agents/sorbet-string-symbol-workflow.md: how Sorbet drives the String/Symbol normalization sweep (tracker task #1) -- declare T.any(String, Symbol) on a method, tighten to one type, run `srb tc`, fix every flagged caller Status: $ bundle exec srb tc No errors! Great job. Why this lands earlier than its dependency order in the tracker suggested: Sorbet is the *driver* for tasks #1, #2, #5, #9, #13, not a follow-up to them. Installing it at default `# typed: false` does nothing on its own (no enforcement, no perf cost), but unlocks the type-narrowing workflow needed to land String/Symbol normalization without grep-and-pray. Files flip to `# typed: true` then `# typed: strict` per the per-file gate (task #20) as cleanup lands. Known incompat: tapioca 0.19 + Ruby 3.2 + sorbet-runtime 0.6.13196 crashes on `tapioca init` in `coerce_and_check_module_types`. Doesn't block the static checker; hand-written stubs cover the small surface area while we're at default typed:false. Workflow doc tracks the upstream fix. Verified: bundle exec prspec spec/ 3599 examples, 0 failures ./clear test transpile-tests/ 432 passed, 0 leaks bundle exec srb tc No errors
cuzzo
added a commit
that referenced
this pull request
May 7, 2026
… fixes
Quick-fix menu support. The 9 Tier 1 + 2 fixable findings (and
anything we add later) now appear as LSP CodeActions when the user
triggers `:lua vim.lsp.buf.code_action()` (or whatever keybinding
their editor maps).
## What's new
- **`src/lsp/code_actions.rb`** — converts cached FixableFindings into
LSP CodeActions. For each finding whose token range overlaps the
client-requested range, we emit one CodeAction per `Fix`:
:auto fixes → kind="quickfix", isPreferred=true
:interactive fixes → kind="refactor", no isPreferred
Each Fix.edits → TextEdits with range computed via Position
Fix.description becomes the action title; the originating
Diagnostic is attached so the client groups actions under the
source error.
- **Server wiring** — new dispatch entry for
`textDocument/codeAction`. The handler reads from
`DocumentStore`'s cached findings (populated by the most recent
`analyze_and_publish` pass), so codeAction is O(findings) — no
re-analysis per request.
- **Capability advertisement** — `initialize` now declares
`codeActionProvider: { codeActionKinds: ["quickfix", "refactor"] }`
so clients know to surface our actions in their UI.
## Range overlap
Two ranges overlap unless one strictly ends before the other begins.
Touching boundaries (e.g. action ends at line 0 char 1, request
starts at line 0 char 1) count as overlapping — that matches Neovim's
default expand-from-cursor selection where the cursor sits on the
boundary character.
## Smoke test
src = "FN main() RETURNS Void ->
x = 5;
WITH RESTRICT x { _ = x; }
END"
→ didOpen + codeAction(line=2)
← {
kind: "quickfix",
title: "Declare 'x' as MUTABLE at its binding site (line 2).",
isPreferred: true,
edit: { documentChanges: [{
textDocument: {uri, version: 1},
edits: [{
range: { start: {line: 1, character: 2}, end: {…} },
newText: "MUTABLE "
}],
}] },
diagnostics: [{ severity: 1, code: "WITH_RESTRICT_NEEDS_MUTABLE", … }],
}
Editor users see "Declare 'x' as MUTABLE" in their quick-fix menu;
accepting the action inserts `MUTABLE ` at the binding site.
## Coverage
100% on src/lsp/ (358/358 lines). 91 LSP specs, 17 of which target
code_actions.rb directly:
- empty-document / no-cache / no-fix paths
- kind + isPreferred mapping for both confidences
- title from Fix.description
- originating Diagnostic attached
- WorkspaceEdit shape (documentChanges → textDocument + edits)
- multi-edit Fix expansion
- range-overlap edge cases (touching, non-overlapping)
- server-level integration: open + codeAction → expected response
Verified:
- 4171 Ruby specs (was 4154 + 17 new) — 0 failures
- 514 transpile-tests — 0 leaks
- module-integration / ffi-integration — green
- Smoke test: editor receives a quickfix with the correct edit.
## Next commit (per plan #5)
Hover support: `textDocument/hover` returns the registry summary +
cause + fix_hint plus the bad/good example from spec annotations,
rendered as markdown.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.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.
The single zig-tsan and zig-coverage CI jobs were hitting their timeout ceilings (60min and 30min respectively). While verifying the sharding fix, found that the TSan job was never actually instrumenting tests --
zig build test -Dsanitize-threadflowed the flag through to unit_tests built in stage2 + Debug, which silently drops the TSan runtime. The actually-instrumented path (test-tsanstep, LLVM + sanitize_thread) was never invoked from CI.Changes:
-Dshard-index/-Dshard-countoptions. Round-robin filter applied to bothtest_step(used by coverage) andtest_tsan_step(used by the new TSan job). Defaults (1, 0) preserve unsharded local behavior.zig build test -Dsanitize-threadtozig build test-tsanso real TSan runs. Matrix-sharded 5-way; per- shard timeout 30min (measured ~7s locally for shard 0 with 9 tests).flags: zig.