feat: add C# Tier 1 extractor#3
Closed
holive wants to merge 6 commits intoCranot:mainfrom
Closed
Conversation
CSharpExtractor handles: namespace (file-scoped + block-scoped), class, interface, struct, enum, method, constructor, field. Includes visibility defaults (context-dependent), compound modifiers, generic signatures with constraints, XML doc comments, and base_list inheritance heuristic. Not yet registered -- Phase 2-6 pending (properties, delegates, records, references, tests).
…ors) Phase 3 of C# Tier 1 extractor. Adds _extract_using (all 4 variants), _extract_call (member access + direct), _extract_new, and wires them into _walk_refs dispatch. Fixes file_scoped_namespace_declaration skipping recursion into its children.
Add "c_sharp": "csharp" grammar alias in parser.py -- without this, all .cs files silently fail to parse because tree-sitter-language-pack expects "csharp" (no underscore). Register CSharpExtractor in registry.py and remove c_sharp fallback entries from generic_lang.py (_EXTENDS_CONFIG, _TRAIT_CONFIG, _PROPERTY_CONFIG). Validated on a personal project (1404 .cs files): 20,061 symbols, 6,890 edges, 15s indexing time.
- extract [HttpGet], [Authorize] etc. as call references from attribute_list - unwrap nullable types (IService?, List<T>?) into type_ref edges, skip builtins - move C# from Tier 2 to Tier 1 in README, add v8.3.0 CHANGELOG entry - update agent reference with verified attribute and nullable AST patterns
Add 25 C# tests to test_languages.py covering core extraction (class, interface, struct, enum, method, constructor, property, delegate, using directives, calls, inheritance, generics) and synthetic scenarios (records, compound modifiers, nested namespaces, XML doc comments, local functions, primary constructors). Fix vacuous assertions in test_comprehensive.py TestCSharp. Fix _extract_using to detect alias directives by checking for '=' punctuation among children, since tree_sitter_language_pack does not produce a name_equals node for using aliases. 1634 passed, 7 skipped, 115 xfailed -- 0 regressions.
…ework detection - extract method names from member_access_expression instead of full chain text, fixing roam symbol/uses resolution (Console.WriteLine -> WriteLine) - recurse into all invocation_expression children to capture chained LINQ calls - add CSharpConvention to test_conventions for separate test project discovery - integrate convention-based test lookup into affected-tests command - add delimiter-aware import pattern matching to prevent false positives (e.g. "next" no longer matches "GetNextPage") - add .NET framework detection patterns (ASP.NET, EF Core, Blazor, etc.)
0545399 to
763f389
Compare
Owner
|
Thank you so much for this incredible contribution, @holive! This is genuinely one of the best community PRs I've seen — the code quality, documentation, real-world validation, and test coverage are all outstanding. What made this PR great
What I polished on topI've merged your work and added a polish commit on top:
All 1,669 tests pass (0 failures), including your 25 original tests + 5 new ones I added. Thanks again for the excellent work — C# is now a proper Tier 1 citizen in roam! |
Cranot
pushed a commit
that referenced
this pull request
Feb 17, 2026
- Add catch/typeof/is/as/cast type_ref extraction to CSharpExtractor - Change attribute references from 'call' to 'type_ref' (correct semantic) - Fix CSharpConvention.languages to include 'c_sharp' (the actual DB key) so convention-based test discovery works with affected-tests command - Optimize _detect_frameworks: scan LIMIT 200 files, precompile regex - Move re/fnmatch imports to module level in cmd_understand.py - Add _BUILTIN_TYPES set for skipping built-in type references - Add 5 new tests: attributes-as-type-ref, catch, typeof, is, as - Clean up leading blank line in csharp_lang.py Built on top of holive's C# Tier 1 extractor PR #3. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cranot
pushed a commit
that referenced
this pull request
Feb 24, 2026
…ions Track A (Epic 1) items #1, #3, #5, #6: - Replace subprocess.run() with Click CliRunner for in-process MCP tool execution. Eliminates ~150-200ms latency per tool call. Subprocess retained as fallback for non-local project roots. - Implement 6 named tool presets replacing binary lite mode: core (16), review (27), refactor (26), debug (27), architecture (29), full. Controlled via ROAM_MCP_PRESET env var. Legacy ROAM_MCP_LITE=0 maps to full. - Shorten all 61 MCP tool descriptions to <60 tokens each via explicit description parameter on _tool() decorator. Python docstrings preserved for documentation; agents receive only the short descriptions. - Add roam_expand_toolset meta-tool (always registered in all presets) that lists available presets and their tool contents. Token impact: core preset with short descriptions = ~1,400 tokens (down from ~36,000 with full tool set + verbose descriptions = 96% reduction). Tests: 62 MCP tests pass (12 new), 2,458 total tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cranot
pushed a commit
that referenced
this pull request
Feb 26, 2026
…ions Track A (Epic 1) items #1, #3, #5, #6: - Replace subprocess.run() with Click CliRunner for in-process MCP tool execution. Eliminates ~150-200ms latency per tool call. Subprocess retained as fallback for non-local project roots. - Implement 6 named tool presets replacing binary lite mode: core (16), review (27), refactor (26), debug (27), architecture (29), full. Controlled via ROAM_MCP_PRESET env var. Legacy ROAM_MCP_LITE=0 maps to full. - Shorten all 61 MCP tool descriptions to <60 tokens each via explicit description parameter on _tool() decorator. Python docstrings preserved for documentation; agents receive only the short descriptions. - Add roam_expand_toolset meta-tool (always registered in all presets) that lists available presets and their tool contents. Token impact: core preset with short descriptions = ~1,400 tokens (down from ~36,000 with full tool set + verbose descriptions = 96% reduction). Tests: 62 MCP tests pass (12 new), 2,458 total tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cranot
pushed a commit
that referenced
this pull request
May 1, 2026
Weakness #3 was "self-rated 91/100, no external user count, distribution PRs queued" — i.e. the bench numbers and competitive scoring are self-evaluated. Three iterations to make the bench credible to outside reviewers: **Iter 1 — regenerate CodeRAG-Bench submission with v12.3 pipeline.** The previous ``bench/retrieve/roam_self.coderag.jsonl`` was generated against the v12.0 pipeline (recall@20 = 0.486). External reviewers who sample-checked it would see ``test_comprehensive.py`` as the top result for "AST clone detection" and conclude the system is broken. Regenerated against the v12.3 pipeline so the JSONL reflects the 0.903 number SUBMISSION.md claims. **Iter 2 — SUBMISSION.md transparency.** Added the full v12.0 → v12.3 iteration log (per-iter recall@K), the exact weight vector used, the commit SHA, and an explicit section on what *not* to read into self-bench numbers. External reviewers can now reproduce by reverting commit 47ce02f and re-running. The "caveats" section names the failure modes still in the suite (six tasks miss a ``commands/cmd_FOO.py`` companion) so nothing is hiding. **Iter 3 — cross-repo regression test.** ``tests/test_retrieve_cross_repo.py`` builds a synthetic Python microservice (auth + payments + notifications, 5 source + 2 test files), indexes it via ``roam init``, and runs 5 generic retrieve tasks against it. Empirically: recall@5 = recall@10 = recall@20 = 1.000, all 5 tasks. Thresholds enforced at 0.9 / 0.95 / 0.95 to catch regression early. This rules out the "iter 1-4 retrieve gains overfit roam-code's specific layout" failure mode. The synthetic repo is *small* and synthetic — formal external validation still requires CodeRAG-Bench / SWE-bench Pro submission. But it does prove the pipeline isn't coupled to roam-code shape. SUBMISSION.md documents this caveat explicitly. Net for weakness #3: bench artefacts now match the headline number, the methodology is auditable, and a CI-gated regression catches non-self-codebase degradation. The "is this actually any good?" question remains a real one until external benchmarks run, but it can no longer hide behind a self-bench number.
Cranot
pushed a commit
that referenced
this pull request
May 1, 2026
Five more rounds of dogfood with all 4 open items closed and 2 new fixes from the wider sweep. Bench preserved (recall@5 0.672 / @10 0.786 / @20 0.900); 375 tests pass across the touched surface. **Round 6 — diagnose commits=0 → index-staleness detection.** Diagnosed: the "0 commits" was a stale-index symptom. ``cmd_critique.py`` was added in commit c33aabd which wasn't in the 187-commit index. ``roam index --force`` brought the index to 203 commits and diagnose showed commits=1. Two fixes: 1. ``metrics_history._compute_health_score`` — the same formula bug we fixed in cmd_health.py last sprint also lived here. ``roam init`` was using this older formula and showing 2/100 in its summary line while ``roam health`` (using the fixed formula) showed 63/100. Inconsistent verdict across commands. Now both report 63/100. 2. ``commands/resolve.index_staleness_hint()`` — new helper that compares ``git_commits.hash ORDER BY timestamp DESC LIMIT 1`` to ``git rev-parse HEAD``. When they differ, returns a one-line ``NOTE:`` message explaining git-derived metrics may be stale and pointing at ``roam index --force``. Wired into ``health``, ``diagnose``, and ``weather`` (the commands most affected by stale git data). Suppressed via ``ROAM_NO_STALENESS_HINT=1`` for CI pipelines that index then mutate. **Round 7 — taint --rules-pack flag.** MEMORY.md and external docs reference "5 starter taint packs (sqli / xss / path-traversal / cmd-injection / deserialization)" but the CLI shipped only ``--rule <substring>`` and ``--rules-dir``. Users reaching for ``--rules-pack`` got a Click error. Added it as a discoverable Choice flag (sugar over ``--rule``) so the docs match the surface. Combinable with ``--rules-dir`` for custom pack directories. **Round 8 — critique bench-relevance hint.** The 'no concerns' verdict on a real refactor of ``rerank.py`` was technically correct (no clones not edited, blast radius low) but silent on the actually-load-bearing question: did you run the bench? Added ``BENCH HINT:`` line that fires when the diff touches hot paths (retrieve/, eval/, graph/, languages/, security/taint/, critique/, oracle/health). Suggests the relevant pytest target + ``roam eval-retrieve`` invocation. The rule set is path-prefix-keyed in ``_BENCH_RELEVANCE_RULES`` so projects without these paths get no hint (silent default). **Round 9 — retrieve file-edge expansion noise.** Two precision filters on top of the original expansion: - ``seed_top_n=30`` — only the strongest first-stage hits seed expansion (was: all 200, where the bottom-150 had near-zero fts and pulled in unrelated files). - ``hub_threshold=20`` — files with file_edges degree above this are skipped as expansion seeds (utility hubs like seeds.py, formatter.py, db.connection imported by 100+ files; their "neighbours" are the entire codebase). Bench: R@5 0.644 → 0.672 (+2.8 pp), R@20 0.892 → 0.900 (+0.8 pp). R@10 dipped 2.8 pp but the user-visible top-K improved. **Round 10 — wider sweep, 2 new fixes.** - cmd_fan default excludes tooling (was showing ``.github/scripts/pr-comment.js`` as #3 hub). Added ``--include-tooling`` opt-in. - cmd_dead default excludes tooling (was reporting dead exports in ``.github/scripts`` and ``dev/command_audit.py`` as top high-confidence findings). Same hint set as cmd_smells / cmd_fan for consistency across the project. Same hint set extracted as ``_TOOLING_PATH_HINTS``; matches ``cmd_smells._file_role_lookup``. Future: lift to a shared ``output/file_roles.py`` if any other command needs it.
Cranot
pushed a commit
that referenced
this pull request
May 4, 2026
…check, workspace fallback - alerts.yaml configurable thresholds (round 4 #3, G, S2): .roam/alerts.yaml overrides health_score / cycles / god_components / layer_violations thresholds. Tiny YAML reader avoids the PyYAML dep when absent. Defaults now live in _DEFAULT_THRESHOLDS (alias _THRESHOLDS retained). - taint Vue/TS rule pack (round 4 feature F): five new YAML rules — js-prototype-pollution, js-localstorage-secrets, vue-template-injection, js-insecure-jwt-decode, js-api-error-leak. Highest-value adds for Vue/Composition-API codebases per the dogfood report. - roam doctor self-check (round 4 S3, K): two new checks — every CLI command in _COMMANDS imports cleanly, MCP tool registry registers successfully. Surfaces the round-4 #15 / #16 class of bug ("documented but missing" / "renamed without alias") at doctor time rather than at agent call-time. - workspace bridge fallback for routes (round 4 feature O): when the route-exists oracle returns indeterminate_workspace, it now scans the parent directory for sibling backend repos (Express, NestJS, Go modules, Cargo, FastAPI, Rails) and surfaces them in the reason text so the user knows where to point `roam ws resolve`.
Cranot
pushed a commit
that referenced
this pull request
May 6, 2026
…egration, real OSS numbers) Second pass after the backward audit. Adds the missing pieces a buyer needs to evaluate the WHOLE product, not just the 3 paid tiers. Complete-product additions - New "Your AI agent talks to Roam" section: positions Roam as an MCP server that Claude Code / Cursor / Codex / Continue can call as a tool. Three-step flow with explicit numbered cards. Closes the biggest gap: the MCP angle was buried in a single sentence. - New "What a Roam review looks like" section with a styled terminal-screenshot block showing actual roam critique output (BLOCK verdict + clones-not-edited / blast-radius / layer-violation reasons). Replaces the missing-screenshot gap without adding an image asset. - Added a 5-cell verbs-grid explaining what understand / retrieve / context / preflight / critique each do in one line. Buyer no longer has to wonder what "preflight" means. - Added 5th FAQ: "Does Roam fit into my CI?" — covers SARIF export, GitHub Actions templates, and the exit-code-5 gate. Enterprise buyers always ask this. - Trust strip rewritten to 2x2: cell #3 now lists the 5 cross-language bridges (Salesforce, REST API, Django, .proto, env-var/config); cell #4 explains the in-toto + cosign + chained log-file evidence pack. Real OSS adoption numbers - Numbers grid expanded to 8 cells: added "5 cross-language bridges" and "54 releases shipped" alongside the existing 190 / 136 / 27 / 2,489+ / 54 / 0 cells. - Hero trust-strip now shows "459 stars · 6k+ installs/month" — real signals, fetched from GitHub + pypistats. Plain-language sweep - "MCP tools for AI agents" -> "tools your AI agent can call". - "in-toto attestations" -> "tamper-proof signed records (in-toto v1)". - "chained audit-trail JSONL" -> "tamper-evident log file". - "phones home" -> "sends nothing back to us". - "it's the floor" -> "it's the minimum bar". - Article 12 FAQ rewritten: explicit about chaining (SHA-256), explicit about cosign verification path. Same content, plainer wording. - "Want us to roll this out for you" -> "Want help getting started". - "white-glove setup" simplified. - "command-line tool" used in subhead instead of "CLI" on first mention. CSP + plumbing - Recomputed CSP sha256 hash for the FAQPage ld+json block (content changed for the Article 12 answer rewrite). - Sitemap lastmod bumped. - Footer now 3-column with "Made in the EU" line — small but signals EU origin to Article-12-curious buyers. Page weight: 7.6 KB HTML compressed, 3.4 KB CSS compressed, 306 KB font (immutable cache). All anchors resolve, no dead links.
Cranot
pushed a commit
that referenced
this pull request
May 7, 2026
Six new content blocks added to the homepage and pricing page based on M2/M3/M6/M7/M9/M11/M13/M14 research findings. The marketing surface goes from feature-list to evidence-led. Homepage additions: - "How Roam fits with your existing stack" 4-cell matrix (M14): vs CodeRabbit/Greptile/Qodo, vs SonarQube/Semgrep, vs Cursor/Claude Code, vs CI. Kills the "Roam replaces my reviewer" objection on first read. - "Three scenarios — what Roam catches in practice" (M9): three case-study cards riffing on real reported incidents (PocketOS Apr 2026, Treadwell memo Mar 2026, DORA/Faros 2025), each with sample CLI output. Concrete > abstract. - "Roam on Roam" dogfood band (M3 trust signal #3 + M13): four real git hashes from refactor commits where Roam flagged its own complexity-99 functions, verifiable on github.com. - 6 new FAQ entries (M11): index time, language coverage, doesn't-replace reviewer, Cloud data shape, Self-Hosted vs offline CLI, why no analytics. Pricing-page additions: - Persona orientation strip above tiers (M7): "Solo? CLI. Team 5-50? Review. Multi-team? Cloud. Regulated? Self-Hosted." Routes the buyer in 10 seconds. - "Most teams start here" badge on Roam Review (M2): visual anchor that was previously missing — every tier looked equally weighted. CSS additions: - .product-card.popular + .popular-badge — accent border, badge ribbon - .persona-band — band style for the orientation strip - .scenarios-grid + .scenario — case-study card pattern - .dogfood-band + .dogfood-list — verifiable-evidence band Performance impact: - Homepage compressed weight 9.8 KB -> 13.4 KB (+3.6 KB). - Within 16 KB amended budget (was 12 KB). The added conversion content is worth more than 3.6 KB of edge bandwidth. Three new docs in templates/distribution/landing-page/: - PERFORMANCE-BUDGET.md (M24): per-asset caps and verification commands - MEASUREMENT.md (M29): how we measure conversion without analytics — CF Web Analytics + PyPI stats + email replies + Search Console - WAITLIST.md (M19): mailto-first now; CF Worker + form upgrade path documented for when public Roam Review beta opens What stayed in place: - Hero H1 unchanged ("Your AI writes the code. Roam tells you what else it broke.") — strong, sticky, persona-true. The 8 alternatives from M1 are documented for A/B but no swap is confidence-clear. - Trust strip cleaned (M1 finding) — scale signal moved earlier, GitHub stars deprioritized. - All existing copy and tier pricing unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cranot
pushed a commit
that referenced
this pull request
May 7, 2026
…check, workspace fallback - alerts.yaml configurable thresholds (round 4 #3, G, S2): .roam/alerts.yaml overrides health_score / cycles / god_components / layer_violations thresholds. Tiny YAML reader avoids the PyYAML dep when absent. Defaults now live in _DEFAULT_THRESHOLDS (alias _THRESHOLDS retained). - taint Vue/TS rule pack (round 4 feature F): five new YAML rules — js-prototype-pollution, js-localstorage-secrets, vue-template-injection, js-insecure-jwt-decode, js-api-error-leak. Highest-value adds for Vue/Composition-API codebases per the dogfood report. - roam doctor self-check (round 4 S3, K): two new checks — every CLI command in _COMMANDS imports cleanly, MCP tool registry registers successfully. Surfaces the round-4 #15 / #16 class of bug ("documented but missing" / "renamed without alias") at doctor time rather than at agent call-time. - workspace bridge fallback for routes (round 4 feature O): when the route-exists oracle returns indeterminate_workspace, it now scans the parent directory for sibling backend repos (Express, NestJS, Go modules, Cargo, FastAPI, Rails) and surfaces them in the reason text so the user knows where to point `roam ws resolve`.
Cranot
pushed a commit
that referenced
this pull request
May 7, 2026
…egration, real OSS numbers) Second pass after the backward audit. Adds the missing pieces a buyer needs to evaluate the WHOLE product, not just the 3 paid tiers. Complete-product additions - New "Your AI agent talks to Roam" section: positions Roam as an MCP server that Claude Code / Cursor / Codex / Continue can call as a tool. Three-step flow with explicit numbered cards. Closes the biggest gap: the MCP angle was buried in a single sentence. - New "What a Roam review looks like" section with a styled terminal-screenshot block showing actual roam critique output (BLOCK verdict + clones-not-edited / blast-radius / layer-violation reasons). Replaces the missing-screenshot gap without adding an image asset. - Added a 5-cell verbs-grid explaining what understand / retrieve / context / preflight / critique each do in one line. Buyer no longer has to wonder what "preflight" means. - Added 5th FAQ: "Does Roam fit into my CI?" — covers SARIF export, GitHub Actions templates, and the exit-code-5 gate. Enterprise buyers always ask this. - Trust strip rewritten to 2x2: cell #3 now lists the 5 cross-language bridges (Salesforce, REST API, Django, .proto, env-var/config); cell #4 explains the in-toto + cosign + chained log-file evidence pack. Real OSS adoption numbers - Numbers grid expanded to 8 cells: added "5 cross-language bridges" and "54 releases shipped" alongside the existing 190 / 136 / 27 / 2,489+ / 54 / 0 cells. - Hero trust-strip now shows "459 stars · 6k+ installs/month" — real signals, fetched from GitHub + pypistats. Plain-language sweep - "MCP tools for AI agents" -> "tools your AI agent can call". - "in-toto attestations" -> "tamper-proof signed records (in-toto v1)". - "chained audit-trail JSONL" -> "tamper-evident log file". - "phones home" -> "sends nothing back to us". - "it's the floor" -> "it's the minimum bar". - Article 12 FAQ rewritten: explicit about chaining (SHA-256), explicit about cosign verification path. Same content, plainer wording. - "Want us to roll this out for you" -> "Want help getting started". - "white-glove setup" simplified. - "command-line tool" used in subhead instead of "CLI" on first mention. CSP + plumbing - Recomputed CSP sha256 hash for the FAQPage ld+json block (content changed for the Article 12 answer rewrite). - Sitemap lastmod bumped. - Footer now 3-column with "Made in the EU" line — small but signals EU origin to Article-12-curious buyers. Page weight: 7.6 KB HTML compressed, 3.4 KB CSS compressed, 306 KB font (immutable cache). All anchors resolve, no dead links.
Cranot
pushed a commit
that referenced
this pull request
May 7, 2026
Six new content blocks added to the homepage and pricing page based on M2/M3/M6/M7/M9/M11/M13/M14 research findings. The marketing surface goes from feature-list to evidence-led. Homepage additions: - "How Roam fits with your existing stack" 4-cell matrix (M14): vs CodeRabbit/Greptile/Qodo, vs SonarQube/Semgrep, vs Cursor/Claude Code, vs CI. Kills the "Roam replaces my reviewer" objection on first read. - "Three scenarios — what Roam catches in practice" (M9): three case-study cards riffing on real reported incidents (PocketOS Apr 2026, Treadwell memo Mar 2026, DORA/Faros 2025), each with sample CLI output. Concrete > abstract. - "Roam on Roam" dogfood band (M3 trust signal #3 + M13): four real git hashes from refactor commits where Roam flagged its own complexity-99 functions, verifiable on github.com. - 6 new FAQ entries (M11): index time, language coverage, doesn't-replace reviewer, Cloud data shape, Self-Hosted vs offline CLI, why no analytics. Pricing-page additions: - Persona orientation strip above tiers (M7): "Solo? CLI. Team 5-50? Review. Multi-team? Cloud. Regulated? Self-Hosted." Routes the buyer in 10 seconds. - "Most teams start here" badge on Roam Review (M2): visual anchor that was previously missing — every tier looked equally weighted. CSS additions: - .product-card.popular + .popular-badge — accent border, badge ribbon - .persona-band — band style for the orientation strip - .scenarios-grid + .scenario — case-study card pattern - .dogfood-band + .dogfood-list — verifiable-evidence band Performance impact: - Homepage compressed weight 9.8 KB -> 13.4 KB (+3.6 KB). - Within 16 KB amended budget (was 12 KB). The added conversion content is worth more than 3.6 KB of edge bandwidth. Three new docs in templates/distribution/landing-page/: - PERFORMANCE-BUDGET.md (M24): per-asset caps and verification commands - MEASUREMENT.md (M29): how we measure conversion without analytics — CF Web Analytics + PyPI stats + email replies + Search Console - WAITLIST.md (M19): mailto-first now; CF Worker + form upgrade path documented for when public Roam Review beta opens What stayed in place: - Hero H1 unchanged ("Your AI writes the code. Roam tells you what else it broke.") — strong, sticky, persona-true. The 8 alternatives from M1 are documented for A/B but no swap is confidence-clear. - Trust strip cleaned (M1 finding) — scale signal moved earlier, GitHub stars deprioritized. - All existing copy and tier pricing unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cranot
pushed a commit
that referenced
this pull request
May 7, 2026
Six new content blocks added to the homepage and pricing page based on M2/M3/M6/M7/M9/M11/M13/M14 research findings. The marketing surface goes from feature-list to evidence-led. Homepage additions: - "How Roam fits with your existing stack" 4-cell matrix (M14): vs CodeRabbit/Greptile/Qodo, vs SonarQube/Semgrep, vs Cursor/Claude Code, vs CI. Kills the "Roam replaces my reviewer" objection on first read. - "Three scenarios — what Roam catches in practice" (M9): three case-study cards riffing on real reported incidents (PocketOS Apr 2026, Treadwell memo Mar 2026, DORA/Faros 2025), each with sample CLI output. Concrete > abstract. - "Roam on Roam" dogfood band (M3 trust signal #3 + M13): four real git hashes from refactor commits where Roam flagged its own complexity-99 functions, verifiable on github.com. - 6 new FAQ entries (M11): index time, language coverage, doesn't-replace reviewer, Cloud data shape, Self-Hosted vs offline CLI, why no analytics. Pricing-page additions: - Persona orientation strip above tiers (M7): "Solo? CLI. Team 5-50? Review. Multi-team? Cloud. Regulated? Self-Hosted." Routes the buyer in 10 seconds. - "Most teams start here" badge on Roam Review (M2): visual anchor that was previously missing — every tier looked equally weighted. CSS additions: - .product-card.popular + .popular-badge — accent border, badge ribbon - .persona-band — band style for the orientation strip - .scenarios-grid + .scenario — case-study card pattern - .dogfood-band + .dogfood-list — verifiable-evidence band Performance impact: - Homepage compressed weight 9.8 KB -> 13.4 KB (+3.6 KB). - Within 16 KB amended budget (was 12 KB). The added conversion content is worth more than 3.6 KB of edge bandwidth. Three new docs in templates/distribution/landing-page/: - PERFORMANCE-BUDGET.md (M24): per-asset caps and verification commands - MEASUREMENT.md (M29): how we measure conversion without analytics — CF Web Analytics + PyPI stats + email replies + Search Console - WAITLIST.md (M19): mailto-first now; CF Worker + form upgrade path documented for when public Roam Review beta opens What stayed in place: - Hero H1 unchanged ("Your AI writes the code. Roam tells you what else it broke.") — strong, sticky, persona-true. The 8 alternatives from M1 are documented for A/B but no swap is confidence-clear. - Trust strip cleaned (M1 finding) — scale signal moved earlier, GitHub stars deprioritized. - All existing copy and tier pricing unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cranot
pushed a commit
that referenced
this pull request
May 7, 2026
…egration, real OSS numbers) Second pass after the backward audit. Adds the missing pieces a buyer needs to evaluate the WHOLE product, not just the 3 paid tiers. Complete-product additions - New "Your AI agent talks to Roam" section: positions Roam as an MCP server that Claude Code / Cursor / Codex / Continue can call as a tool. Three-step flow with explicit numbered cards. Closes the biggest gap: the MCP angle was buried in a single sentence. - New "What a Roam review looks like" section with a styled terminal-screenshot block showing actual roam critique output (BLOCK verdict + clones-not-edited / blast-radius / layer-violation reasons). Replaces the missing-screenshot gap without adding an image asset. - Added a 5-cell verbs-grid explaining what understand / retrieve / context / preflight / critique each do in one line. Buyer no longer has to wonder what "preflight" means. - Added 5th FAQ: "Does Roam fit into my CI?" — covers SARIF export, GitHub Actions templates, and the exit-code-5 gate. Enterprise buyers always ask this. - Trust strip rewritten to 2x2: cell #3 now lists the 5 cross-language bridges (Salesforce, REST API, Django, .proto, env-var/config); cell #4 explains the in-toto + cosign + chained log-file evidence pack. Real OSS adoption numbers - Numbers grid expanded to 8 cells: added "5 cross-language bridges" and "54 releases shipped" alongside the existing 190 / 136 / 27 / 2,489+ / 54 / 0 cells. - Hero trust-strip now shows "459 stars · 6k+ installs/month" — real signals, fetched from GitHub + pypistats. Plain-language sweep - "MCP tools for AI agents" -> "tools your AI agent can call". - "in-toto attestations" -> "tamper-proof signed records (in-toto v1)". - "chained audit-trail JSONL" -> "tamper-evident log file". - "phones home" -> "sends nothing back to us". - "it's the floor" -> "it's the minimum bar". - Article 12 FAQ rewritten: explicit about chaining (SHA-256), explicit about cosign verification path. Same content, plainer wording. - "Want us to roll this out for you" -> "Want help getting started". - "white-glove setup" simplified. - "command-line tool" used in subhead instead of "CLI" on first mention. CSP + plumbing - Recomputed CSP sha256 hash for the FAQPage ld+json block (content changed for the Article 12 answer rewrite). - Sitemap lastmod bumped. - Footer now 3-column with "Made in the EU" line — small but signals EU origin to Article-12-curious buyers. Page weight: 7.6 KB HTML compressed, 3.4 KB CSS compressed, 306 KB font (immutable cache). All anchors resolve, no dead links.
Cranot
pushed a commit
that referenced
this pull request
May 7, 2026
Six new content blocks added to the homepage and pricing page based on M2/M3/M6/M7/M9/M11/M13/M14 research findings. The marketing surface goes from feature-list to evidence-led. Homepage additions: - "How Roam fits with your existing stack" 4-cell matrix (M14): vs CodeRabbit/Greptile/Qodo, vs SonarQube/Semgrep, vs Cursor/Claude Code, vs CI. Kills the "Roam replaces my reviewer" objection on first read. - "Three scenarios — what Roam catches in practice" (M9): three case-study cards riffing on real reported incidents (PocketOS Apr 2026, Treadwell memo Mar 2026, DORA/Faros 2025), each with sample CLI output. Concrete > abstract. - "Roam on Roam" dogfood band (M3 trust signal #3 + M13): four real git hashes from refactor commits where Roam flagged its own complexity-99 functions, verifiable on github.com. - 6 new FAQ entries (M11): index time, language coverage, doesn't-replace reviewer, Cloud data shape, Self-Hosted vs offline CLI, why no analytics. Pricing-page additions: - Persona orientation strip above tiers (M7): "Solo? CLI. Team 5-50? Review. Multi-team? Cloud. Regulated? Self-Hosted." Routes the buyer in 10 seconds. - "Most teams start here" badge on Roam Review (M2): visual anchor that was previously missing — every tier looked equally weighted. CSS additions: - .product-card.popular + .popular-badge — accent border, badge ribbon - .persona-band — band style for the orientation strip - .scenarios-grid + .scenario — case-study card pattern - .dogfood-band + .dogfood-list — verifiable-evidence band Performance impact: - Homepage compressed weight 9.8 KB -> 13.4 KB (+3.6 KB). - Within 16 KB amended budget (was 12 KB). The added conversion content is worth more than 3.6 KB of edge bandwidth. Three new docs in templates/distribution/landing-page/: - PERFORMANCE-BUDGET.md (M24): per-asset caps and verification commands - MEASUREMENT.md (M29): how we measure conversion without analytics — CF Web Analytics + PyPI stats + email replies + Search Console - WAITLIST.md (M19): mailto-first now; CF Worker + form upgrade path documented for when public Roam Review beta opens What stayed in place: - Hero H1 unchanged ("Your AI writes the code. Roam tells you what else it broke.") — strong, sticky, persona-true. The 8 alternatives from M1 are documented for A/B but no swap is confidence-clear. - Trust strip cleaned (M1 finding) — scale signal moved earlier, GitHub stars deprioritized. - All existing copy and tier pricing unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cranot
added a commit
that referenced
this pull request
May 8, 2026
- Add catch/typeof/is/as/cast type_ref extraction to CSharpExtractor - Change attribute references from 'call' to 'type_ref' (correct semantic) - Fix CSharpConvention.languages to include 'c_sharp' (the actual DB key) so convention-based test discovery works with affected-tests command - Optimize _detect_frameworks: scan LIMIT 200 files, precompile regex - Move re/fnmatch imports to module level in cmd_understand.py - Add _BUILTIN_TYPES set for skipping built-in type references - Add 5 new tests: attributes-as-type-ref, catch, typeof, is, as - Clean up leading blank line in csharp_lang.py Built on top of holive's C# Tier 1 extractor PR #3. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cranot
added a commit
that referenced
this pull request
May 8, 2026
…ions Track A (Epic 1) items #1, #3, #5, #6: - Replace subprocess.run() with Click CliRunner for in-process MCP tool execution. Eliminates ~150-200ms latency per tool call. Subprocess retained as fallback for non-local project roots. - Implement 6 named tool presets replacing binary lite mode: core (16), review (27), refactor (26), debug (27), architecture (29), full. Controlled via ROAM_MCP_PRESET env var. Legacy ROAM_MCP_LITE=0 maps to full. - Shorten all 61 MCP tool descriptions to <60 tokens each via explicit description parameter on _tool() decorator. Python docstrings preserved for documentation; agents receive only the short descriptions. - Add roam_expand_toolset meta-tool (always registered in all presets) that lists available presets and their tool contents. Token impact: core preset with short descriptions = ~1,400 tokens (down from ~36,000 with full tool set + verbose descriptions = 96% reduction). Tests: 62 MCP tests pass (12 new), 2,458 total tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cranot
added a commit
that referenced
this pull request
May 8, 2026
Weakness #3 was "self-rated 91/100, no external user count, distribution PRs queued" — i.e. the bench numbers and competitive scoring are self-evaluated. Three iterations to make the bench credible to outside reviewers: **Iter 1 — regenerate CodeRAG-Bench submission with v12.3 pipeline.** The previous ``bench/retrieve/roam_self.coderag.jsonl`` was generated against the v12.0 pipeline (recall@20 = 0.486). External reviewers who sample-checked it would see ``test_comprehensive.py`` as the top result for "AST clone detection" and conclude the system is broken. Regenerated against the v12.3 pipeline so the JSONL reflects the 0.903 number SUBMISSION.md claims. **Iter 2 — SUBMISSION.md transparency.** Added the full v12.0 → v12.3 iteration log (per-iter recall@K), the exact weight vector used, the commit SHA, and an explicit section on what *not* to read into self-bench numbers. External reviewers can now reproduce by reverting commit 2c59fc0 and re-running. The "caveats" section names the failure modes still in the suite (six tasks miss a ``commands/cmd_FOO.py`` companion) so nothing is hiding. **Iter 3 — cross-repo regression test.** ``tests/test_retrieve_cross_repo.py`` builds a synthetic Python microservice (auth + payments + notifications, 5 source + 2 test files), indexes it via ``roam init``, and runs 5 generic retrieve tasks against it. Empirically: recall@5 = recall@10 = recall@20 = 1.000, all 5 tasks. Thresholds enforced at 0.9 / 0.95 / 0.95 to catch regression early. This rules out the "iter 1-4 retrieve gains overfit roam-code's specific layout" failure mode. The synthetic repo is *small* and synthetic — formal external validation still requires CodeRAG-Bench / SWE-bench Pro submission. But it does prove the pipeline isn't coupled to roam-code shape. SUBMISSION.md documents this caveat explicitly. Net for weakness #3: bench artefacts now match the headline number, the methodology is auditable, and a CI-gated regression catches non-self-codebase degradation. The "is this actually any good?" question remains a real one until external benchmarks run, but it can no longer hide behind a self-bench number.
Cranot
added a commit
that referenced
this pull request
May 8, 2026
Five more rounds of dogfood with all 4 open items closed and 2 new fixes from the wider sweep. Bench preserved (recall@5 0.672 / @10 0.786 / @20 0.900); 375 tests pass across the touched surface. **Round 6 — diagnose commits=0 → index-staleness detection.** Diagnosed: the "0 commits" was a stale-index symptom. ``cmd_critique.py`` was added in commit 67ea975 which wasn't in the 187-commit index. ``roam index --force`` brought the index to 203 commits and diagnose showed commits=1. Two fixes: 1. ``metrics_history._compute_health_score`` — the same formula bug we fixed in cmd_health.py last sprint also lived here. ``roam init`` was using this older formula and showing 2/100 in its summary line while ``roam health`` (using the fixed formula) showed 63/100. Inconsistent verdict across commands. Now both report 63/100. 2. ``commands/resolve.index_staleness_hint()`` — new helper that compares ``git_commits.hash ORDER BY timestamp DESC LIMIT 1`` to ``git rev-parse HEAD``. When they differ, returns a one-line ``NOTE:`` message explaining git-derived metrics may be stale and pointing at ``roam index --force``. Wired into ``health``, ``diagnose``, and ``weather`` (the commands most affected by stale git data). Suppressed via ``ROAM_NO_STALENESS_HINT=1`` for CI pipelines that index then mutate. **Round 7 — taint --rules-pack flag.** MEMORY.md and external docs reference "5 starter taint packs (sqli / xss / path-traversal / cmd-injection / deserialization)" but the CLI shipped only ``--rule <substring>`` and ``--rules-dir``. Users reaching for ``--rules-pack`` got a Click error. Added it as a discoverable Choice flag (sugar over ``--rule``) so the docs match the surface. Combinable with ``--rules-dir`` for custom pack directories. **Round 8 — critique bench-relevance hint.** The 'no concerns' verdict on a real refactor of ``rerank.py`` was technically correct (no clones not edited, blast radius low) but silent on the actually-load-bearing question: did you run the bench? Added ``BENCH HINT:`` line that fires when the diff touches hot paths (retrieve/, eval/, graph/, languages/, security/taint/, critique/, oracle/health). Suggests the relevant pytest target + ``roam eval-retrieve`` invocation. The rule set is path-prefix-keyed in ``_BENCH_RELEVANCE_RULES`` so projects without these paths get no hint (silent default). **Round 9 — retrieve file-edge expansion noise.** Two precision filters on top of the original expansion: - ``seed_top_n=30`` — only the strongest first-stage hits seed expansion (was: all 200, where the bottom-150 had near-zero fts and pulled in unrelated files). - ``hub_threshold=20`` — files with file_edges degree above this are skipped as expansion seeds (utility hubs like seeds.py, formatter.py, db.connection imported by 100+ files; their "neighbours" are the entire codebase). Bench: R@5 0.644 → 0.672 (+2.8 pp), R@20 0.892 → 0.900 (+0.8 pp). R@10 dipped 2.8 pp but the user-visible top-K improved. **Round 10 — wider sweep, 2 new fixes.** - cmd_fan default excludes tooling (was showing ``.github/scripts/pr-comment.js`` as #3 hub). Added ``--include-tooling`` opt-in. - cmd_dead default excludes tooling (was reporting dead exports in ``.github/scripts`` and ``dev/command_audit.py`` as top high-confidence findings). Same hint set as cmd_smells / cmd_fan for consistency across the project. Same hint set extracted as ``_TOOLING_PATH_HINTS``; matches ``cmd_smells._file_role_lookup``. Future: lift to a shared ``output/file_roles.py`` if any other command needs it.
Cranot
added a commit
that referenced
this pull request
May 8, 2026
…check, workspace fallback - alerts.yaml configurable thresholds (round 4 #3, G, S2): .roam/alerts.yaml overrides health_score / cycles / god_components / layer_violations thresholds. Tiny YAML reader avoids the PyYAML dep when absent. Defaults now live in _DEFAULT_THRESHOLDS (alias _THRESHOLDS retained). - taint Vue/TS rule pack (round 4 feature F): five new YAML rules — js-prototype-pollution, js-localstorage-secrets, vue-template-injection, js-insecure-jwt-decode, js-api-error-leak. Highest-value adds for Vue/Composition-API codebases per the dogfood report. - roam doctor self-check (round 4 S3, K): two new checks — every CLI command in _COMMANDS imports cleanly, MCP tool registry registers successfully. Surfaces the round-4 #15 / #16 class of bug ("documented but missing" / "renamed without alias") at doctor time rather than at agent call-time. - workspace bridge fallback for routes (round 4 feature O): when the route-exists oracle returns indeterminate_workspace, it now scans the parent directory for sibling backend repos (Express, NestJS, Go modules, Cargo, FastAPI, Rails) and surfaces them in the reason text so the user knows where to point `roam ws resolve`.
Cranot
added a commit
that referenced
this pull request
May 8, 2026
…egration, real OSS numbers) Second pass after the backward audit. Adds the missing pieces a buyer needs to evaluate the WHOLE product, not just the 3 paid tiers. Complete-product additions - New "Your AI agent talks to Roam" section: positions Roam as an MCP server that Claude Code / Cursor / Codex / Continue can call as a tool. Three-step flow with explicit numbered cards. Closes the biggest gap: the MCP angle was buried in a single sentence. - New "What a Roam review looks like" section with a styled terminal-screenshot block showing actual roam critique output (BLOCK verdict + clones-not-edited / blast-radius / layer-violation reasons). Replaces the missing-screenshot gap without adding an image asset. - Added a 5-cell verbs-grid explaining what understand / retrieve / context / preflight / critique each do in one line. Buyer no longer has to wonder what "preflight" means. - Added 5th FAQ: "Does Roam fit into my CI?" — covers SARIF export, GitHub Actions templates, and the exit-code-5 gate. Enterprise buyers always ask this. - Trust strip rewritten to 2x2: cell #3 now lists the 5 cross-language bridges (Salesforce, REST API, Django, .proto, env-var/config); cell #4 explains the in-toto + cosign + chained log-file evidence pack. Real OSS adoption numbers - Numbers grid expanded to 8 cells: added "5 cross-language bridges" and "54 releases shipped" alongside the existing 190 / 136 / 27 / 2,489+ / 54 / 0 cells. - Hero trust-strip now shows "459 stars · 6k+ installs/month" — real signals, fetched from GitHub + pypistats. Plain-language sweep - "MCP tools for AI agents" -> "tools your AI agent can call". - "in-toto attestations" -> "tamper-proof signed records (in-toto v1)". - "chained audit-trail JSONL" -> "tamper-evident log file". - "phones home" -> "sends nothing back to us". - "it's the floor" -> "it's the minimum bar". - Article 12 FAQ rewritten: explicit about chaining (SHA-256), explicit about cosign verification path. Same content, plainer wording. - "Want us to roll this out for you" -> "Want help getting started". - "white-glove setup" simplified. - "command-line tool" used in subhead instead of "CLI" on first mention. CSP + plumbing - Recomputed CSP sha256 hash for the FAQPage ld+json block (content changed for the Article 12 answer rewrite). - Sitemap lastmod bumped. - Footer now 3-column with "Made in the EU" line — small but signals EU origin to Article-12-curious buyers. Page weight: 7.6 KB HTML compressed, 3.4 KB CSS compressed, 306 KB font (immutable cache). All anchors resolve, no dead links.
Cranot
added a commit
that referenced
this pull request
May 8, 2026
Six new content blocks added to the homepage and pricing page based on M2/M3/M6/M7/M9/M11/M13/M14 research findings. The marketing surface goes from feature-list to evidence-led. Homepage additions: - "How Roam fits with your existing stack" 4-cell matrix (M14): vs CodeRabbit/Greptile/Qodo, vs SonarQube/Semgrep, vs Cursor/Claude Code, vs CI. Kills the "Roam replaces my reviewer" objection on first read. - "Three scenarios — what Roam catches in practice" (M9): three case-study cards riffing on real reported incidents (PocketOS Apr 2026, Treadwell memo Mar 2026, DORA/Faros 2025), each with sample CLI output. Concrete > abstract. - "Roam on Roam" dogfood band (M3 trust signal #3 + M13): four real git hashes from refactor commits where Roam flagged its own complexity-99 functions, verifiable on github.com. - 6 new FAQ entries (M11): index time, language coverage, doesn't-replace reviewer, Cloud data shape, Self-Hosted vs offline CLI, why no analytics. Pricing-page additions: - Persona orientation strip above tiers (M7): "Solo? CLI. Team 5-50? Review. Multi-team? Cloud. Regulated? Self-Hosted." Routes the buyer in 10 seconds. - "Most teams start here" badge on Roam Review (M2): visual anchor that was previously missing — every tier looked equally weighted. CSS additions: - .product-card.popular + .popular-badge — accent border, badge ribbon - .persona-band — band style for the orientation strip - .scenarios-grid + .scenario — case-study card pattern - .dogfood-band + .dogfood-list — verifiable-evidence band Performance impact: - Homepage compressed weight 9.8 KB -> 13.4 KB (+3.6 KB). - Within 16 KB amended budget (was 12 KB). The added conversion content is worth more than 3.6 KB of edge bandwidth. Three new docs in templates/distribution/landing-page/: - PERFORMANCE-BUDGET.md (M24): per-asset caps and verification commands - MEASUREMENT.md (M29): how we measure conversion without analytics — CF Web Analytics + PyPI stats + email replies + Search Console - WAITLIST.md (M19): mailto-first now; CF Worker + form upgrade path documented for when public Roam Review beta opens What stayed in place: - Hero H1 unchanged ("Your AI writes the code. Roam tells you what else it broke.") — strong, sticky, persona-true. The 8 alternatives from M1 are documented for A/B but no swap is confidence-clear. - Trust strip cleaned (M1 finding) — scale signal moved earlier, GitHub stars deprioritized. - All existing copy and tier pricing unchanged. 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.
Summary
csharp_lang.py, ~1,050 lines), replacing the generic Tier 2 walker.csfiles produced zero output becauseGRAMMAR_ALIASESwas missing the"c_sharp": "csharp"mappingThis was listed as a roadmap item in the README. The implementation follows the existing pattern established by
java_lang.py, adapted for C#-specific AST differences.What changed
Bug fix: C# parsing was silently broken
parser.pymaps.cs->"c_sharp", buttree_sitter_language_packexpects"csharp"(no underscore). Without the grammar alias,parse_file()returned(None, None, None)for every.csfile. The existingTestCSharptests intest_comprehensive.pypassed vacuously (one matched a TypeScript fixture, the other matched a substring of the "no symbols" message). This PR fixes both the alias and the tests.New:
CSharpExtractorinsrc/roam/languages/csharp_lang.pySymbols extracted:
required), delegate, event, indexerReferences extracted:
importusingdirectives -- standard,static, alias (using Foo = ...),globalcallinvocation_expression(method calls),object_creation_expression(new)inherits/implementsbase_listwith positional heuristic (see design note below)attributeattribute_list([HttpGet],[Authorize], etc.)type_refIService?,List<IHandler>?), skipping builtinsC#-specific handling (where it diverges from Java):
internal, nested types toprivate, interface/enum members topublic. Each modifier is a separatemodifiernode (not a singlemodifierscontainer like Java).protected internalandprivate protectedare two separate AST nodes that must be collected and combined.base_listdisambiguation: C# puts base class and interfaces in onebase_listnode (Java has separatesuperclass/interfacesfields). This uses a positional heuristic: first entry without anIprefix =inherits, everything else =implements. Correct >95% of the time; the only false positives are classes with I-prefixed names likeImmutableArrayappearing as the sole base entry.file_scoped_namespace_declarationis a sibling of type declarations in the AST, not a parent. The walker tracks the current namespace and applies it to subsequent siblings.///chains instead of/** */blocks. Walksprev_siblingto collect consecutive comment nodes.parameter_liston class/struct/record is NOT a named field in tree-sitter-c-sharp -- requires child iteration instead ofchild_by_field_name("parameters").returns(nottypelike Java). Delegates and local functions usetypeinstead. Getting this wrong produces silent empty signatures.Note on edge count comparison
The previous Tier 2 config in
generic_lang.pyhadc_sharpentries in both_EXTENDS_CONFIGand_TRAIT_CONFIGusing the samebase_list+identifierquery, which would have double-counted everybase_listentry as both an "inherits" and "implements" reference (if parsing had worked). The Tier 1 extractor classifies each entry as one or the other. Fewer total edges does not mean worse extraction -- it means correct classification.Files changed
src/roam/languages/csharp_lang.pysrc/roam/index/parser.py"c_sharp": "csharp"toGRAMMAR_ALIASESsrc/roam/languages/registry.py"c_sharp"to_DEDICATED_EXTRACTORS, add elif branch in_create_extractor()src/roam/languages/generic_lang.pyc_sharpentries from_EXTENDS_CONFIG,_TRAIT_CONFIG,_PROPERTY_CONFIGtests/test_languages.pyTestCSharpExtractionclass (25 tests)tests/test_comprehensive.pyTestCSharpvacuous assertionsREADME.mdCHANGELOG.mdReal-world validation
Tested on a production C# codebase (~1,550
.csfiles):Previous Tier 2 output: 0 symbols, 0 edges (grammar alias bug).
Test plan
tests/test_languages.pycovering all symbol kinds, reference kinds, visibility defaults, generics, and CLI integrationtests/test_comprehensive.pypytest tests/test_languages.py -k csharp -vto verify tests passroam initon a C# project to spot-check output