Repository navigation
feat(config): read baton's config file - #29
Merged
Merged
Conversation
internal/config reads config.json in baton's folder under the user's config folder, so nothing goes into a work repo: settings for every repo at its top, and a section per repo in "repos", keyed by the remote's URL as its host and path, so that a repo's HTTPS and SSH clones share a section. The repo's section lies over the top, and the top over baton's own settings, one setting at a time; a setting left out, or given its zero value, keeps the one below (decision 49). The settings so far: each role's model, reasoning effort and AI credits cap, the orchestrator's extra tools (nudge's by default), the round cap and the branch prefix. baton checks the whole file when it reads it, the other repos' sections too, and refuses a member that it doesn't know or that comes twice, a role that it doesn't know, a model or a tool that starts with a dash, a reasoning effort or a cap that copilot doesn't take (fact 31; fact 10's least cap, 30), a negative round cap, extra tools for any role but the orchestrator, and a repo's key in another form, with the form wanted. The next step, config-cli, gives the settings to baton pane and baton feature start; the other settings come with their steps.
|
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.



Brief (lead)
Goal. baton's settings come from a config file of the user's, outside the repo (decision 16): each role's model, reasoning effort and AI credits cap, the orchestrator's extra tools, the round cap and the branch prefix, for every repo and per repo. This step is the package that reads and checks the file. The next one,
config-cli, wires it intobaton paneandbaton feature start.Scope.
internal/config, withLoad(configDir, remote):config.jsonin baton's folder under the user's config folder; a missing file gives baton's own settings;repos, keyed by the remote's URL as its host and path (github.com/codedogapp/batonfor its HTTPS, SSH and scp-like URLs); a local path keeps its path;extraTools) replaces the one below whole, and[]gives none;copilotthat it stops.The plan:
config-clirow.AGENTS.md: the lead merges Renovate's green pull requests, once their release notes show no breaking change and their pins match their tags, and asks about a red one or a major update (the user's OK of 2026-11-03, asked through nudge when Renovate opened its first two, chore(deps): update jdx/mise-action action to v5.2.6 #27 and chore(deps): update sonarsource/sonarqube-scan-action action to v8.4.1 #28, merged under it).
Out of scope.
repo.Remoteand the README's config section:config-cli.Acceptance criteria.
Loadgives baton's own settings.mise run checkis green, and every probe is caught.Engineer
internal/config/config.go:SettingsandRole, with their JSON names;defaults(): Claude Opus 5.5 for every role, nudge's two tools for the orchestrator, 3 rounds,feature/;Load: reads strictly withencoding/json/v2(RejectUnknownMembers; v2 refuses duplicate names and matches names case-sensitively), checks, then lays the layers;Settings.withandRole.with:cmp.Orper setting; a nilExtraToolskeeps the list below.internal/config/check.go:check: the top first, then the repos' sections in the order of their keys; each key must be inkey's form;Settings.checkandRole.check, roles in name order:key: a URL's host and path, without scheme, user and port; git's scp-like[user@]host:pathwhen no slash comes before the colon, with the user cut at the last@, as ssh does; then one trailing/and.gittrimmed.config_test.go: the defaults, both layers, the remotes' forms (17 URLs and paths);refusals_test.go: 16 exact refusals, 10 JSON errors (by substring), and a read error.QA
mise run checkgreen: lint 0 issues,internal/config100% covered, 99.2% in total, govulncheck none.Load: a missing file as an error; the read error dropped; unknown members taken; no check, or no repos' check; the path left out of the error; no repo layer, or no top layer; the layers swapped; the repo found by its raw remote.cmp.Orturned around;extraToolsreplaced only when non-empty, or always.[]taken, empty and dash names taken, only the first tool checked.key: no://test; the port kept; a slash before the colon ignored; the scp user kept, or cut at the first@; leading or trailing slashes, or.git, kept; the trims swapped.copilot's least cap. The spike found that copilot refuses a cap below 30 (fact 10), and the first draft took any cap of 0 or more. A probe with a bad
--reasoning-effort, so copilot stopped before any session, showed:--max-ai-creditsparses as a number, fractions too;-1reads as a flag.baton now refuses a cap that is neither 0 nor 30 or more (fact 31). A test takes exactly 30.
json/v2's errors change their wording. One run in ten failed the
[]row: json/v2 picks "cannot" or "unable to" at random, so that nobody compares its errors as text. The row now matches "unmarshal JSON array"; 300 runs in a row pass.An scp-like user with an
@(me@example.com@github.com:…) is cut at the last@, as ssh does; a test pins it.feat/for baton's repo only.config-cli's smoke run will.go-buildfolders).Review
roundCap: 0keeps the layer below, and the branch prefix can't be set empty. This is flagged in decision 49 for the end review; a pointer type per setting would tell "absent" from "zero" at the cost of every caller's nil checks.GitHub.comdoesn't match agithub.comsection. Rare, and documented.Go config.layers), next to the JSON pointer that says where the problem is. Acceptable for a config error.