Skip to content

bar-fmt: lua codemod, workspace integration, LLM type-triage (rollup) - #57

Draft
keithharvey wants to merge 34 commits into
beyond-all-reason:masterfrom
keithharvey:bar-fmt-03-llm
Draft

bar-fmt: lua codemod, workspace integration, LLM type-triage (rollup)#57
keithharvey wants to merge 34 commits into
beyond-all-reason:masterfrom
keithharvey:bar-fmt-03-llm

Conversation

@keithharvey

@keithharvey keithharvey commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

The bar-fmt migration as one PR (19 commits at the stack tip): bar-lua-codemod tooling and tests, workspace integration (check recipes, editor wiring, migrate::stylua-cleanup, the generic bar::restack stack rebaser), the LLM type-triage layer with the generation capstone, and the migrate:: moves that host every pipeline branch and PR on the canonical repo (#8395–#8410).

keithharvey and others added 18 commits July 22, 2026 19:29
bar-lua-codemod parses BAR Lua with emmylua_parser (the same front-end
family as emmylua_check/emmylua_ls) at Lua51, doc-comment analysis off.
Transforms collect byte-range edits over the rowan CST and splice them
into the original source, so untouched bytes are untouched by
construction. cst.rs carries the shared helpers: parse gate on
SyntaxError-kind diagnostics only, bracketed-string-key extraction that
tolerates trivia, and the function-declaration-name exclusion.
codemod-cargo.sh runs cargo inside bar-dev, where the toolchain lives.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
x["y"] -> x.y and ["y"] = -> y = for string keys that are valid,
non-reserved identifiers. Raw quoted content only — escapes and long
strings never convert. Injects a space when ] abutted a word character
so .identifier doesn't merge with what follows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Spring.GetMyTeamID / GetMyAllyTeamID / GetMyPlayerID -> the canonical
GetLocal* names, wherever the prefix is the bare Spring global. Bracket
access and non-Spring prefixes are left alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Spring.I18N / Utilities / Debug / Lava / GetModOptionsCopy — BAR's own
helpers riding the Spring table — move to the BAR namespace. Handles the
_G.Spring.Module spelling too; function-declaration names stay put.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bar::check / bar::check-errors run emmylua_check inside bar-dev against
BAR's .emmyrc.json; check-errors re-derives its exit code from the
error count so warnings don't fail CI. Adds the devtools .emmyrc.json,
points the VS Code template at the exported emmylua wrappers, extracts
Sim/Units/Scripts docs in lua::library, and makes distrobox a hard
setup requirement — the whole toolchain lives in the container.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bar::codemod-build / codemod-test wrap codemod-cargo.sh. Migrations get
their own bar::migrate:: namespace — adoption-dated entries listed in
order, retired to [private] ~6 months after adoption. The 2026-07
stylua-cleanup entry replays the transform set (bracket-to-dot,
rename-aliases, detach-bar-modules) plus stylua onto the local BAR
checkout — the idempotent 'transform your branch, then merge' path the
README callout documents.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The codemod scanned everything stylua ignores: .lux and
recoil-lua-library tool dirs, and mapgenerator — whose
mapinfo_template.lua is a ${}-placeholder template, not valid Lua.
Old runs never hit it because a local skip-worktree bit kept the file
off disk; upstream touched the file, checkout rewrote the index entry,
the bit dropped, and the template resurfaced as a parse failure.
Explicit excludes replace the hidden state. No output change: the
baseline transform chain has zero conversions under mapgenerator.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
llm-type-triage.sh chunks emmylua_check errors and dispatches parallel
LLM workers (claude --print, or the openai worker via BACKEND=openai —
hence python3-pip in bar-dev) that fix annotations per file. The
codemod-prereq SKILL.md is the categorization rulebook: error pattern ->
idempotent fix recipe, first match wins. claude/claude.md carries the
cross-repo agent context.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
generate-branches.sh deterministically rebuilds fmt, the mig-* leaves,
the mig rollup, and the fmt-llm capstone (env layer + gen(llm) commit),
with PR-body generation, the museum table, and stacked-PR base
overrides. bar::migrate::stylua-cleanup-generate fronts it ([private] —
generation stays out of the listing), wrapping execution in
$CREDENTIALS_RUNNER so the triage workers inherit LLM-backend
credentials; the tracking-issue template ties the PR stack together.
Generated PR bodies now point at the migrate:: names, so the next
--update-prs run rewrites the published bodies to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Same discovery as the replay recipe: mapgenerator/mapinfo_template.lua
(a ${}-placeholder template, not valid Lua) was kept off disk by a
local skip-worktree bit, which upstream's touch of the file silently
dropped — resurfacing it as a parse failure that aborts generation.
CODEMOD_EXCLUDES mirrors .styluaignore (vendored utils, .lux,
recoil-lua-library, mapgenerator) in the three transform runners and
their PR-body command docs. Verified: both the full_moon baseline
binary and the emmylua binary report 2,166 scanned / 0 errors with the
skip set — the baseline run's exact scan count.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
link_gh_stack used plain gh, which the bar-dev container doesn't have —
the extension check always failed inside distrobox and stack linking
silently skipped. Route it through resolve_host_gh/host_exec like every
other gh call (the 916e302 hardening missed this one).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
GitHub's native stacked PRs reject fork-headed PRs, and the whole
fmt -> mig -> fmt-llm-source -> fmt-llm chain was fork-headed. The
branches already live on the canonical repo, so the chain PRs are
recreated same-repo (#8395/#8396/#8397/#8398) and the fork originals
(#7199/#7229/#7447/#8235) closed with cross-links. Constants follow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
No fork-headed PRs anywhere — native stacked PRs reject them and
reviewers live upstream. The fork keeps mirror pushes only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Completes the no-fork-PRs convention: bracket/rename/detach leaves and
the two carried leaves recreated with heads on beyond-all-reason
(#8401/#8402/#8403/#8404/#8405); fork originals (#7287/#7288/#7289/
#7437/#7438) closed with cross-links.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
GitHub rejects --base on PRs in a native stack even as a no-op — the
stack owns the base. edit_pr checks the current base and only sends
--base when it needs to move.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Chain links move to #8395–#8398 (the fmt-llm line still pointed at the
pre-#8235 capstone). The tooling line links the three-layer devtools
stack with org beyond-all-reason#17 as the entry point — keithharvey has no push access
to beyond-all-reason/BAR-Devtools, so the devtools stack hosts on the
fork and beyond-all-reason#17 stays the org-visible umbrella. DEVTOOLS_PR points at the
generation layer (3/3).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The hash was recorded outside the commit branch, so a transform whose
content arrived via a prereq cherry-pick filed the previous commit's SHA
under its own name — three of six entries were wrong. Match subjects
against origin/master..HEAD instead, and warn when the count is short.

BLAME_TRANSFORMS narrows the file to mechanical rewrites: the gen(hand)
pair is a hand restructure and a pure addition, where --ignore-revs has
nothing earlier to attribute to.
The LLM pass shipped gui_chat.lua in a state that would not load: a
partial rename, a dropped table field, a stripped namespace prefix, and
fifteen lines of shadowing recomputation the analyzer cannot see.
The old hook ran stylua over the whole repo and never re-staged, so the
unformatted version committed anyway while ~30 unrelated files were left
dirty. It checked nothing.

Now it checks only the staged .lua and refuses, filtering .styluaignore
itself because stylua honours it only for discovered paths, not for ones
passed explicitly. setup-hooks refuses to install while .stylua.toml and
.gitattributes disagree about line endings — a --check hook would reject
every correctly-formatted file.
From review on #8398: the pass commented out a ${} placeholder to make a
parse error go away, and repaired a nil set-entry to an object that
happened to be in scope rather than to the true the read sites imply.
Checking working-tree files ties the gate to .gitattributes eol=crlf vs
stylua's line_endings, and those disagree. Staged content is always LF,
so checking the blob is both what git will record and immune to the
question. Drops the config-mismatch guard, which is now moot.
@@ -0,0 +1,185 @@
# Type Triage Worker Prompt (OpenAI variant)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think this file is good to include, mostly as a blueprint for how to do this sort of subagent/orchestrator script in the future. This PR does new things so having the some sub-agent stuff in claude/ provides helpful rails for future folks trying the same thing.

@@ -0,0 +1,1084 @@
---

@keithharvey keithharvey Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the skill file so subagents bail if they don't hit a known rule while walking through EmmyLua errors.

git_bar routes git through host_exec, so a commit that creates files
writes them on the host while stylua reads them from inside bar-dev. The
container sees the dirents but not the contents, and the pass dies with
"failed to read ./types/Debug.lua: No such file or directory" —
intermittently, and only for the one prereq that adds files.

Resolves a host stylua the same way resolve_host_gh does, with an
in-container fallback that warns.
target/ is unanchored so it covers bar-mission-kit as well as
bar-lua-codemod, and the packaged mission-kit server binary is ignored by
path — it is a build output, not a source artifact.
A branch pushed at the same tip as its base reads to GitHub as merged: it
closes the PR, credits the pusher, and deletes the branch. A merged PR
cannot be reopened, so #8403 is gone for good.

It happens when a run dies between 'checkout -B <leaf> fmt' and the
transform commit and the empty leaf is pushed anyway. Refuse instead.
Tooling stack is one PR now, not three. Adds the mission-kit PR as its
own checklist item, the pre-commit hook to the command list, and
.git-blame-ignore-revs to what the stack delivers — with the caveat that
git blame aborts on branches predating it, which contributors will hit
before the capstone lands.

Error count tracks the measured baseline and says so, since it moves with
master.
The rebase logic was never BAR-specific. It now lives in repos.just taking
the repo as an argument, so two copies would be two ways to do one thing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant