feat(autoland): per-repo lander model/effort; fix runs resolve on the AFK chain #190

Merged
dominik.polakovics merged 1 commit from afk/189 into main 2026-07-20 19:41:20 +02:00

Closes #189

Lander model/effort knobs

  • New nullable repo columns lander_model / lander_effort (migration pair 0016_lander_model_effort.sql, both dialects, lockstep-numbered). NULL = inherit the existing resolution — no existing repo gains an override.
  • Both LaunchLander and LaunchEscalate feed the columns as strict per-spawn requests into ResolveModelEffort via a shared landerRequestModelEffort helper (one validation class, one set of knobs — no separate escalate override). An unknown lander_model/lander_effort fails the launch loudly; an effort in the provider union but outside the resolved model's own catalog is rejected (the #156 per-model rule holds, for free, by resolving model+effort in one call).
  • Round-trips through the repo PATCH endpoint and is editable in the repo settings autoland card beside "Lander agent", with catalogs resolved live against the lander's effective provider (lander agent if picked, else the repo's own chain).
  • Deliberate design point: no write-time catalog validation on the PATCH surface (unlike lander_provider's registry check). Model/effort catalogs are per-provider and dynamic (#156/#157) and the lander's effective provider isn't knowable at write time — strictness is enforced where it's meaningful, at launch. Pinned by tests on both surfaces.

Fix runs join the normal AFK chain

  • The #182/ADR-0048 authoring-run inheritance is reversed by deletion: fixProvider, the model/effort warn-fallback ladder in LaunchFix, and store.AuthoringRunForBranch (plus its test) are gone. LaunchFix and the producer's auth gate both resolve with empty requests through ResolveProvider/ResolveModelEffort under RunKindFix, which is already an AFK kind — repo AFK override → global AFK override → base.
  • Consequence, intended: a branch authored by one provider can be fixed by another if that's what the repo's AFK chain says. The adopt is detached; nothing provider-specific carries over.
  • ADR-0048 amended in place (Status paragraph + the per-repo-settings pin), quoting the superseded clause per the repo's amendment convention. CONTEXT.md needed no change — it never named the autoland knobs.

Tests

  • Store round-trip extended to the two new columns (set / nil-default / patch-set / patch-clear).
  • 8 new lander tests: unknown model/effort fail both lander and escalate launches; valid values are recorded exactly on the run row; per-model effort rejection; NULL inherits the base resolution (newly pinned).
  • The #182 inheritance pins rewritten to pin the reversal: TestSpawnOnce_rejectSpawnsFixRunOnAFKChain (authoring row sonnet/high, AFK overrides fable/xhigh, base opus[1m]/max → fix run must carry fable/xhigh) and the fix-forward cycle integration test keeps its seeded haiku/low authoring row precisely to prove it is ignored.
  • HTTP API: set/clear/round-trip plus a deliberate accepts-unknown-string-at-write pin; web: picker → PATCH body, clear → null, inherit labels.

Verified: go build ./..., go test ./... (all packages), golangci-lint run (0 issues), tsc --noEmit, vitest run (871 tests), eslint, prettier --check, vite build — all green.

🤖 Generated with Claude Code

Closes #189 ## Lander model/effort knobs - New nullable repo columns `lander_model` / `lander_effort` (migration pair `0016_lander_model_effort.sql`, both dialects, lockstep-numbered). NULL = inherit the existing resolution — no existing repo gains an override. - Both `LaunchLander` and `LaunchEscalate` feed the columns as strict per-spawn requests into `ResolveModelEffort` via a shared `landerRequestModelEffort` helper (one validation class, one set of knobs — no separate escalate override). An unknown `lander_model`/`lander_effort` fails the launch loudly; an effort in the provider union but outside the resolved model's own catalog is rejected (the #156 per-model rule holds, for free, by resolving model+effort in one call). - Round-trips through the repo PATCH endpoint and is editable in the repo settings autoland card beside "Lander agent", with catalogs resolved live against the lander's effective provider (lander agent if picked, else the repo's own chain). - Deliberate design point: **no write-time catalog validation** on the PATCH surface (unlike `lander_provider`'s registry check). Model/effort catalogs are per-provider and dynamic (#156/#157) and the lander's effective provider isn't knowable at write time — strictness is enforced where it's meaningful, at launch. Pinned by tests on both surfaces. ## Fix runs join the normal AFK chain - The #182/ADR-0048 authoring-run inheritance is reversed **by deletion**: `fixProvider`, the model/effort warn-fallback ladder in `LaunchFix`, and `store.AuthoringRunForBranch` (plus its test) are gone. `LaunchFix` and the producer's auth gate both resolve with empty requests through `ResolveProvider`/`ResolveModelEffort` under `RunKindFix`, which is already an AFK kind — repo AFK override → global AFK override → base. - Consequence, intended: a branch authored by one provider can be fixed by another if that's what the repo's AFK chain says. The adopt is detached; nothing provider-specific carries over. - ADR-0048 amended in place (Status paragraph + the per-repo-settings pin), quoting the superseded clause per the repo's amendment convention. CONTEXT.md needed no change — it never named the autoland knobs. ## Tests - Store round-trip extended to the two new columns (set / nil-default / patch-set / patch-clear). - 8 new lander tests: unknown model/effort fail both lander and escalate launches; valid values are recorded exactly on the run row; per-model effort rejection; NULL inherits the base resolution (newly pinned). - The #182 inheritance pins rewritten to pin the reversal: `TestSpawnOnce_rejectSpawnsFixRunOnAFKChain` (authoring row sonnet/high, AFK overrides fable/xhigh, base opus[1m]/max → fix run must carry fable/xhigh) and the fix-forward cycle integration test keeps its seeded haiku/low authoring row precisely to prove it is ignored. - HTTP API: set/clear/round-trip plus a deliberate accepts-unknown-string-at-write pin; web: picker → PATCH body, clear → null, inherit labels. Verified: `go build ./...`, `go test ./...` (all packages), `golangci-lint run` (0 issues), `tsc --noEmit`, `vitest run` (871 tests), `eslint`, `prettier --check`, `vite build` — all green. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(autoland): per-repo lander model/effort; fix runs resolve on the AFK chain
All checks were successful
ci / native (pull_request) Successful in 6m40s
b686586a53
Two corrections to how autoland runs pick model, effort, and provider
(issue #189):

Lander knobs: new nullable repo columns lander_model and lander_effort
(migration 0016, both dialects), siblings of lander_provider. NULL keeps
the inherited resolution; non-NULL is a STRICT per-spawn request fed to
ResolveModelEffort in both LaunchLander and LaunchEscalate — an unknown
value fails the launch loudly, and an effort outside the resolved
model's own catalog is rejected (the #156 per-model rule). Editable in
the repo settings autoland card; the PATCH surface accepts any
non-empty string deliberately (catalogs are per-provider and dynamic,
strictness lives at launch).

Fix runs: the ADR-0048/#182 authoring-run inheritance is reversed by
deletion. LaunchFix and the producer's auth gate now resolve provider,
model, and effort through the normal AFK chain (repo AFK override →
global AFK override → base) with empty requests; fixProvider, the
warn-fallback ladder, and store.AuthoringRunForBranch are gone. A
branch authored by one provider may now legitimately be fixed by
another — the adopt is detached, nothing carries over. ADR-0048
amended in place.

Closes #189

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/coding-lab!190
No description provided.