Vendors govindbanura/tree-sitter-vbnet (MIT, (c) 2025 Govind Banura) at 538b7087bf80 (tag v0.1-beta, upstream HEAD) with CodeGraph's real-world VB.NET patch (colbymchenry/codegraph docs/grammars/tree-sitter-vbnet.patch at fe7542b6f6a4, MIT, (c) 2026 Colby Mchenry), as a self-maintained fork in tools/tree-sitter-vbnet/. This is the precondition for VB.NET extraction (#1179, folding in #2885); it registers no language yet. Why this grammar: it is the licensed one. CodeAnt-AI/tree-sitter-vb-dotnet, which #1179 was built on, carries no license and cannot be vendored. Why the patch: upstream checks in grammar.js only and does not parse the code VB.NET projects are made of. Unpatched, the Single literals in every WinForms .Designer.vb (New SizeF(6.0!, 13.0!)) and body-less MustOverride members are ERROR nodes. The 2026-10-06 revision of the patch is pinned because it also keeps names that begin with a keyword whole: the earlier revision (the one #2885 carried) turns `Sub NewItem()` into an ERROR and `Public SharedCache As Integer` into a Shared field named Cache. Provenance by hash: the patch file is byte-identical to CodeGraph's (blob37918d81); upstream grammar.js at the pin is the patch's pre-image (21c8523), and tools/tree-sitter-vbnet/grammar.js minus its 41-line provenance header is the post-image (c9c1d85), as is scanner.c (8334fdb). parser.c is generated here with tree-sitter-cli 0.25.10 (ABI 15); two independent generations are byte-identical. No upstream script, package hook or binary was run or vendored. - internal/cbm/vendored/grammars/vbnet/: the generated parser.c, CodeGraph's external scanner.c (two stateless tokens), the tree_sitter/ headers, upstream's MIT LICENSE byte-identical, and CodeGraph's MIT text as LICENSE-codegraph: the scanner and the patched rules are CodeGraph's work, so its notice has to ship with the binary too. - internal/cbm/grammar_vbnet.c: compiles and links tree_sitter_vbnet. No CBMLanguage, extension or alias routes to it yet; extraction adds them, with `vb` and `visualbasic` meaning VB.NET (VB6 keeps its own name). - MANIFEST.md (fork note, forks table, 163 grammars, ABI recount), THIRD_PARTY.md (fork list and a vbnet section; the stale "160 pre-generated parsers" now reads 163), scripts/vendored-checksums.txt, and the FORKS entry in scripts/audit-license-provenance.py. - README.md and the Chocolatey nuspec say 163 languages: the language-count contract defines the count as the vendored grammar directories. - tests/test_parse_coverage.c: real VB.NET (a WinForms Designer partial class, Handles, Inherits/Implements, MustOverride, #Region, Property, keyword-prefixed names) parses with no ERROR node. The case fails on unpatched upstream (8 ERROR nodes) and on the earlier patch revision (1). Refs #1178, #1179, #2885 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
scripts/ — the canonical leg entries
The doctrine (enforced, not advisory): a venue may provision a machine;
only a canonical leg script may exercise the product. Local CI, PR CI, the
dry run and the release all call the SAME files below — venues differ only in
host specs, architecture and inputs, never in what a leg does. Platform
differences (arm64 sanitizer flags, native Windows behavior, the Linux portable
binary) live INSIDE these scripts, once, never per-venue.
tests/test_venue_parity_contract.sh (run as Step 0j of every test leg) turns
any violation — inline harness logic in a workflow, a bypassed wrapper, a
missing --help — into a red build.
Every entry answers --help (authoritative, agent-oriented: modes, env, exit
codes) and rejects unknown flags with exit 2 + Please consult --help.
The legs
| leg | entry | what a run gives you |
|---|---|---|
| test | test.sh |
DEFAULT = the venue leg: static contracts (Step 0a–0r) + CLEAN ASan+UBSan build + all suites via the parallel harness + prod-binary guards. --suites a,b = iteration mode (incremental rebuild, subset, seconds). --tsan = the ThreadSanitizer leg. --contracts-only = the static contract steps alone (PR CI's contracts job for docs-only and non-product changes). CLANGARM64 gets CI's trap-UBSan flags automatically. |
| package wrappers | ci/test-package-wrappers.sh |
Go, npm, and PyPI runtime-set publication/lock suites on the current host. CI runs the same entry on Linux and Windows so both platform lock implementations gate. |
| build | build.sh |
CLEAN production runtime set (native executable + authenticated integration asset; --with-ui adds one content-addressed UI pack). ccache via env.sh makes repeats fast; CCACHE_COMPILERCHECK=content guarantees a hit is byte-identical to a cold compile — never stale. --version, STATIC=1, BUILD_DIR=. |
| lint | lint.sh |
clang-tidy + cppcheck + clang-format (+ no-skips policy). --ci = the CI gate set (no clang-tidy). Drives the same make targets as make lint/lint-ci. |
| smoke (unix) | smoke-local.sh |
Stages a full release fixture, serves it on a kernel-assigned port, runs smoke-test.sh (ALL phases incl. download/install/update E2E) inside a disposable HOME/XDG/TMP sandbox. ui variant makes a missing verified UI pack a FAILURE. CBM_SMOKE_ARTIFACT_DIR = smoke an extracted release artifact verbatim (release mode). |
| smoke (windows) | ../test-infrastructure/vm/vm-smoke.sh |
Same verified runtime-set contract on the real Windows VM, plus the user-PATH registry guard (prepare/verify/cleanup). |
| smoke-invariants | smoke-invariants.sh |
Production-path resilience battery (MCP handshake, all tools invocable, malformed-input handling, supervised crash/hang recovery) — no fixture server or install E2E. smoke.yml runs an explicitly seam-enabled build on the WIDEST source matrix; release artifacts remain seam-free and use the release-shaped smoke legs above. |
| soak | soak-legs.sh |
The release-gating soak SEQUENCE: quick then query-leak (the #581 detector — never reindexes, so RSS growth = query-path leak), each guarded by a completion-summary check. --legs quick for the ASan single-leg variant. Duration is per leg. |
Internal harnesses — never called directly by a venue (the contract forbids
it): smoke-test.sh (phases; wrappers provide fixture server + sandbox),
soak-test.sh (one soak run; soak-legs.sh provides the sequence + guards),
run-tests-parallel.sh (reached through test.sh), which sources
suite-failure-report.sh for its end-of-run failure summary (failure sites,
sanitizer report, running test, last lines) and for test-logs/failed/, the
logs of every suite that did not end green.
Conventions
- Exit codes: 0 = pass · 2 = usage error · 90 = guard (a run died without its completion summary — never counts as green) · anything else = the leg's real failure.
- Iteration is a flag, not a side-tool: the fast paths (
--suites,--legs) are modes of the SAME entry the gates run, so a dev loop can never drift from the venue behaviour. - Env sandboxing: the smoke wrappers neutralize every agent-config destination override; a smoke can never scribble on your real config.
Recommended workflows
- Iterating on a change:
scripts/test.sh --suites <suite>(seconds, incremental, same ASan+UBSan flags as the gate). List suites:build/c/test-runner --list-suites. Debugging a Windows-on-ARM trap: re-run withSANITIZE=for a plain build, or use the emulatedwin.sh ubsan-*pair for full diagnostics. - Before any push (the 3-OS ladder):
scripts/test.sh(macOS, full) →./test-infrastructure/run.sh full(Linux + TSan + smoke) →test-infrastructure/vm/win.sh test-par+guards+smoke-install(+soakwhen the change touches memory/daemon paths). - Concurrency-touching change: add
scripts/test.sh --tsanearly — the same leg CI gates on. - Release-shaped verification:
CBM_SMOKE_ARTIFACT_DIR=<extracted artifact> scripts/smoke-local.sh <binary> [ui]smokes exactly what would ship. - A leg is red in CI but green locally: first suspect environment shape,
not code — the preflights (
win.shautomatic;scripts/ci/preflight-docker.sh) andtest-infrastructure/README.md's residuals list cover the knowable differences.
See scripts/ci/README.md for the CI plumbing and
test-infrastructure/README.md for the venue map.