Skip to content

plugin: index leaves incidental languages out of a build that names no --lang (#1835) - #1962

Open
swapnilpaliwal-sd wants to merge 1 commit into
0.2.1from
fix/incidental-language
Open

swapnilpaliwal-sd wants to merge 1 commit into
0.2.1from
fix/incidental-language

Conversation

@swapnilpaliwal-sd

@swapnilpaliwal-sd swapnilpaliwal-sd commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1972

Part of #1835.

What

With no --lang, axiomcode index built a graph for every language it found and chose the main language by file count. One .py file beside three trivial .js files became a JavaScript repository with a Python graph beside it. A Python backend with a few .js build scripts got a second graph, a second section in every answer, and a cold JavaScript engine compile.

The rule (ax_fresh.py choose, read by axiomcode-build)

  • Main language: the one with the most code. Code is counted in non-blank lines, with each file capped at 1,000 lines so a vendored file cannot decide it.
  • Incidental language: any other language with fewer than 20 source files AND either under 5% of the code or under 100 lines in all. It is not built.
  • Named, not hidden: every index ends by naming what it left out and the --lang that includes it, for example:
    not indexed, incidental to this python repository (under 20 files, and under 5% of its code or 100 lines): javascript (3 files, 3 lines); to include: axiomcode index --lang python,javascript
    
  • An explicit --lang always wins. Web (HTML/CSS) follows the same rule.
  • Each language is still its own graph. Nothing is linked across languages.

How 20 files and 5% were chosen

  • Measured on 42 corpus repositories, 14 each of Python, Java and C#. 35 have a second language, 79 second languages in all.
  • 41 of those have under 20 files, and they split with a gap: 33 are at 3.8% of the code or less (stray scripts, a docs theme, samples), and 8 are at 6.0% or more (small frontends, a site's pages). 5% sits in the gap.
  • Every second language with 20 or more files is still built. 26 of the 42 repositories still get more than one graph.
  • Weighting by code changes the main language in 2 of the 42: two Python projects that file count had called TypeScript and JavaScript.

Consistency

Every reader of the main language (queries, context, the hooks, MCP) takes it from the built graph's run.language, so they agree with the build without changes of their own.

Docs

README Get Started shows axiomcode index --lang <language> and states the rule in one sentence.

Tests

  • tests/incidental_languages.py, 18 checks, all pass:
    • 1 py + 3 js gives python only, with the note.
    • 40 py + 3 js build scripts gives python only, and answers have one section.
    • Control: a balanced TypeScript + Python repository builds both graphs.
    • Control: --lang javascript gives javascript only.
    • --lang python,javascript builds both.
    • On the base, the first two shapes build two graphs, and both controls hold.
  • tests/run.py --lang python: 445/445. tests/engine_choice.py passes.
  • tests/multi_language.py: 4 failures, all of which also fail on the base (6 failures there).
  • tests/publish_order.py: the same 5 failures as on the base, by name.
  • Fixture changes, and why:
    • The multi_language.py and publish_order.py fixtures had 5-16 lines per language, which makes them incidental under the new rule. Each gets a filler module of 100+ lines per language that no check reads.
    • The maven-web check now expects its single 6-line Java class to be named as incidental instead of built.

@swapnilpaliwal-sd swapnilpaliwal-sd added the bug Something isn't working label Oct 14, 2026
@swapnilpaliwal-sd swapnilpaliwal-sd added python Python javascript JavaScript plugin the axiomcode plugin: skill + MCP layer bug Something isn't working labels Oct 14, 2026
…o --lang

`axiomcode index` with no --lang built a graph for every language it found and
chose the main one by file count. One .py file beside three trivial .js files
became a JavaScript repository with a Python graph beside it. A Python backend
with a few .js build scripts got a second graph, a second section in every
answer, and a cold JavaScript engine compile.

The choice now lives in ax_fresh.py (`choose`), which axiomcode-build reads in
place of `count`:

- The main language is the one with the most code: non-blank lines, with each
  file counted up to 1,000 lines so that a vendored blob cannot decide it. Web
  is the main language only when no other language has a file, as before.
- Any other language is incidental, and is not built, when it has fewer than
  20 source files AND either under 5% of the repository's code or under 100
  lines in all. A share means nothing in a repository of four files, which is
  why the line floor exists.
- What is left out is named at the end of every index, together with the
  --lang that includes it. An explicit --lang always wins. Web (HTML/CSS)
  follows the same rule.

How N=20 and X=5% were chosen: I measured the language mix of 42 corpus
repositories, 14 each of Python, Java and C#. 35 of them have a second
language, 79 second languages in all. 41 of those have fewer than 20 files,
and they split with a gap: 33 are at 3.8% of the code or less (stray scripts,
a docs theme, a sample, a vendored widget), and the other 8 are at 6.0% or
more (a small frontend, a site's pages). 5% sits in that gap. Every second
language with 20 or more files is still built. Under the rule, 26 of the 42
repositories still get more than one graph. Weighting the main language by
code changes it in 2 of the 42, both Python projects that file count had
called TypeScript and JavaScript.

Every reader of the main language takes it from the built graph (the
run.language row: ax_langs, context, the hooks through _where, MCP through the
verbs), so queries, hooks and MCP agree with the build without changes of
their own. A file in a skipped language is outside every indexed language, so
editing it does not make the graph stale.

README Get Started now shows `axiomcode index --lang <language>` and gives the
rule in one sentence.

Tests: tests/incidental_languages.py covers the rule on the numbers, plus real
builds. 1 py + 3 js gives python only, with the note. 40 py + 3 js build
scripts gives python only. A balanced TypeScript + Python repository gives
both graphs (control). --lang javascript gives javascript (control). On the base,
the first two shapes build two graphs and both controls hold.

Fixture changes, and why: the multi_language.py and publish_order.py fixtures
were 5-16 lines per language, which makes them incidental under the new rule.
Each now carries a filler module of 100+ lines per language that no check
asks about. The maven-web check in multi_language.py now expects its single
6-line Java class to be named as incidental instead of built. Its path check
reads the verb's own answer (AXIOMCODE_RAW), which names the callee's file.

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

Labels

bug Something isn't working javascript JavaScript plugin the axiomcode plugin: skill + MCP layer python Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant