Skip to content

Routing for sg and vale should include lists of supported languages #151

Closed

Description

@theCodeDrift

In order for agents to clearly identify if a rule can be built locally, the list of supported languages for sg and vale should be in the routing recipe.

Remaining are the two GitHub Actions YAML rules — pr-workflow-no-branches-filter and pr-workflow-ready-for-review. Both depend on ast-grep handling YAML, which I still haven't verified; if it doesn't, route will likely send them to runtime, which needs a login. Want me to press on to #4?

Discovered in @taskless/cli-nightly@0.11.0-20260824013916xe788b11

Activity

  1. theCodeDrift commented on Aug 24, 2026

    @theCodeDrift
    MemberAuthor

    Yes — ast-grep supports YAML here, and both GitHub Actions rules belong in create-sg-rule with no login.

    The pinned binary (@ast-grep/cli@0.41.0, exact-pinned in packages/cli/package.json) enumerates 26 languages in sg run -h:

    Bash, C, Cpp, CSharp, Css, Elixir, Go, Haskell, Hcl, Html, Java, JavaScript, Json, Kotlin, Lua, Nix, Php, Python, Ruby, Rust, Scala, Solidity, Swift, Tsx, TypeScript, Yaml

    pr-workflow-no-branches-filter was authored as a real rule (language: Yaml, matching branches: inside a pull_request mapping): taskless verify → ✓, taskless test → ✓. ast-grep gives YAML real node kinds (block_mapping_pair, flow_node, plain_scalar), so route should not have sent these to runtime.

    But a separate bug would have made it look unsupported

    taskless check finds nothing under .github/ for a byte-identical file it finds elsewhere:

    $ taskless check                       → No issues found.
    $ cp .github/workflows/bad.yml notdot/ && taskless check
      notdot/bad.yml:3:5  error[pr-workflow-no-branches-filter] pull_request must not carry a branches filter
    

    ast-grep's walker skips hidden directories by default and runAstGrepScan never passes --no-ignore hidden (packages/cli/src/rules/scan.ts:139-146). No sg rule can see .github/, .circleci/, .vscode/, or .husky/ today. Vale does not have this blind spot — the same run reported .github/HIDDEN.md — so the two static engines disagree about whether .github/ exists. Arguably the higher-priority half of this issue.

    On Vale, the list is not the interesting part — the failure tier is

    Probed against the shipped 3.17.1 (Vale self-reports no format list, so every tier here is measured):

    • native markup: .md .markdown .html .org
    • code comments only: .py .rb .js .jsx .ts .tsx .go .rs .java .c .h .cpp .hpp .cs .php .swift .scala .lua .hs .clj .pl .r .jl .less .proto
    • everything else, including .yml .toml .sh .sql, is linted as whole-file prose — a Vale rule on YAML flags its code, not just its comments
    • .rst .adoc .asciidoc .xml .dita .mdx hard-fail: E100, exit 2, needing rst2html / asciidoctor / an XSLT / dita / mdx2vast, none of which we ship

    That last tier is quiet and total. One such file anywhere takes down the entire Vale pass, not just that file — measured: with a .adoc present, 3 Vale findings dropped to 0 and check still exited on sg's finding alone. Routing a prose rule at an AsciiDoc or reStructuredText repo therefore silently disables every other Vale rule, and nothing in route.txt or create-vale-rule.txt says so.

    Design note — the part worth arguing about

    There is no existing source of truth for either list. The generated src/generated/ast-grep-rule-schema.json types language as a bare string with no enum ($defs.Language is a placeholder); verify never validates it, so any string passes; and detect --json reports repo languages in a different vocabulary (C++ vs ast-grep's Cpp). The binaries are the only authority.

    route.txt currently says nothing about language support — its engine table (agent/route.txt:66-71) is entirely about evidence shape. The closest it comes is conceding that availability is uncertain and telling the agent to pick an engine "whose availability you can assert," while giving it no way to assert it.

    I'd argue against transcribing the lists into the recipe. Two lists that drift on a version bump with nothing to catch them, and prose that quietly stops being true is worse than the current silence — which at least makes the agent ask. Vale's is worse than a list anyway; the useful content is the tiers, including "these six hard-fail."

    Instead: a pinned constant in src/rules/capabilities.ts (pure data, so the Worker-safe prompts/recipes.ts can import it), substituted into the recipes as %(SG_LANGUAGES)s / %(VALE_FORMATS)s, with vendor-contract tests asserting the constant still matches the binaries. That is the pattern test/ast-grep-vendor-contract.test.ts already exists for — exact-pinned binary plus a test that fires on the bump — so the list cannot drift without something going red. ast-grep self-reports via sg run -h; Vale reports nothing, so its tiers get probe-based pins.

    Rejected the third option, extending detect --json with an engines block: openspec/specs/cli-detect/spec.md:100 frames detect as an offline repo scan, engine reach is knowable at build time rather than repo-scan time, and it would cost a third subprocess turn in a recipe already spending two.

    Also worth stating in the recipe: a language absent from both lists is not a reason to escalate to runtime — create-legacy-rule should be checked first, since the repo's own linter may already cover it.

  2. theCodeDrift commented on Aug 25, 2026

    @theCodeDrift
    MemberAuthor

    Implemented by #155 (71f4394), which added both lists to the routing recipe. route now carries:

    • ast-grep's 26 languages, in its own spelling, verbatim into a rule's language: field — with the note that off-list names split two ways: an alias it recognizes (cpp for Cpp) reaches the right parser, while one it does not (C# for CSharp) aborts config parsing and takes every other rule's report down with it.
    • Vale's four format tiers by extension — markup, comments-only, plaintext fallback, and the converter-dependent formats this build excludes whatever is installed on the machine.

    The blocker this issue records is also resolved

    The quoted context is a prior onboarding pass that stopped here:

    Remaining are the two GitHub Actions YAML rules — pr-workflow-no-branches-filter and pr-workflow-ready-for-review. Both depend on ast-grep handling YAML, which I still haven't verified; if it doesn't, route will likely send them to runtime, which needs a login.

    Yaml is on the list, so both are sg rules and neither needs a login. A later onboarding pass reached the same question and had it answered by the recipe rather than stalling — which is this issue's fix working end to end. Both rules are now written, verified, and tested, under the names used above, in #168.

    Closing as done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions