Skip to content

fix(ship): auto-fallback to --agent-mode on unusable LLM provider; fix agent-mode wrong-feature resume - #43

Merged
teragrid merged 3 commits into
mainfrom
fix/agent-mode-fallback-and-issue4
Sep 5, 2026
Merged

teragrid merged 3 commits into
mainfrom
fix/agent-mode-fallback-and-issue4

Conversation

@teragrid

@teragrid teragrid commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • forge ship was documented to have --agent-mode as the escape hatch for a broken/out-of-credit LLM provider (ISSUE 1 in docs/plans/FORGE_SHIP_ISSUES_2026-09-04.md, ai-marketing-platfrom repo), but it required the operator to notice the failure and manually re-invoke with the flag. forge ship now probes the configured provider (same live-call check as forge doctor --llm) and auto-switches to agent mode when a configured provider fails for a permanent reason (invalid/expired key, or the invalid_request_error shape Anthropic uses for "credit balance too low"). FORGE_NO_AGENT_FALLBACK=1 opts out. No-provider-at-all is untouched — that's a different, existing UX path.
  • CRITICAL fix (ISSUE 4, same doc): forge ship --agent-mode run bare (no --name, no description — exactly the hint forge itself prints after a submit) called Bridge.SetFeature("", ""), which blanked the session's recorded feature identity every time. The next resolution of "which feature is this session driving" then had nothing to resume against, and could fall through to an unrelated, pre-existing feature's incomplete checkpoint — silently corrupting its pipeline state if the wrong turn's answer got submitted. SetFeature("", "") is now a no-op when an identity already exists, and the bare-continuation path resolves the missing name/description from the session's own Bridge.Feature() before doing anything else.

Test plan

  • go build ./..., go vet ./...
  • go test ./... (full suite, all packages green)
  • New regression tests: TestSetFeature_BareContinuationPreservesIdentity (agentbridge), existing TestSetFeature_SwitchingFeatureResetsStaleSession still passes
  • Full 13-check forge ship pre-push gate (gofmt, vet, golangci-lint, build, test, govulncheck, go mod verify, forge scan security, forge lint, forge check, 21 QA real-command tests, 12 ship dry-run scenarios) — all green

🤖 Generated with Claude Code

vietking and others added 3 commits September 5, 2026 02:16
…x agent-mode bare-continuation resuming wrong feature

- forge ship now probes the configured LLM provider (mirrors `forge doctor
  --llm`) before a non-agent-mode run. When a provider is configured but a
  live call fails permanently (invalid/expired key, or Anthropic's
  invalid_request_error shape for "credit balance too low"), the run
  automatically switches to --agent-mode instead of hard-failing every
  checkpoint. FORGE_NO_AGENT_FALLBACK=1 opts out. No provider configured at
  all is left untouched (existing stub/hint UX, not this failure).

- Bridge.SetFeature("", "") — the bare continuation forge itself prints as
  the next-step hint after a submit — was blanking the session's recorded
  feature identity on every call, so the next resolution of "which feature
  is this session driving" had nothing to resume against and could fall
  through to an unrelated feature's incomplete checkpoint (ISSUE 4 in
  docs/plans/FORGE_SHIP_ISSUES_2026-09-04.md, ai-marketing-platfrom repo).
  SetFeature("", "") is now a no-op when an identity already exists, and the
  agent-mode bare-continuation path resolves the missing --name/description
  from the session's own Bridge.Feature() first.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…in --dry-run

Addresses ISSUE 5 and ISSUE 3 in docs/plans/FORGE_SHIP_ISSUES_2026-09-04.md
(ai-marketing-platfrom repo), on top of the ISSUE 1/4 fixes already on this
branch.

- CRITICAL: Bridge was documented "not safe for concurrent use", but nothing
  enforced it. checkArch's runParallelArchDebate fires one goroutine per
  reviewer role (6 by default), and every one calls Lookup concurrently
  against the same Bridge in agent mode — an unsynchronized data race on the
  seen/byHash/byOrdinal maps and the pending/paused fields, which the Go
  runtime can surface as a panic or, plausibly, as the multi-minute hang with
  zero output actually observed mid-arch-debate. Bridge now serializes every
  exported method touching shared state behind a mutex (SetFeature calls a
  new unexported resetLocked to avoid re-entering it from Reset). New
  regression test TestLookup_ConcurrentCallsAreSafe reproduces the exact
  six-goroutines-one-operation shape; go test -race already runs nightly.

- --dry-run made real LLM calls and wrote files to disk despite its own help
  text ("without making LLM calls or git operations"). newLLMPipeInteractive
  returned a live, billable pipe whenever a provider was configured, dry-run
  or not — its own doc comment already (incorrectly) claimed otherwise.
  checkSpec/checkArch had no dryRun parameter at all, so previewing a
  not-yet-generated feature unconditionally created .forge/specs/<slug>/ and
  wrote workspace-context.md plus a spec.md/arch.md stub (or real LLM
  output, if credentials worked) — the stray-directory behavior the doc
  observed running exploratory --dry-run probes. Dry-run now always gets a
  nil pipe, and checkSpec/checkArch report what they would generate without
  touching disk when the target artefact doesn't exist yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ck-and-issue4

# Conflicts:
#	CHANGELOG.md
#	internal/agentbridge/agentbridge_test.go
@teragrid
teragrid merged commit e552051 into main Sep 5, 2026
20 checks passed
@teragrid
teragrid deleted the fix/agent-mode-fallback-and-issue4 branch September 5, 2026 02:50
teragrid pushed a commit that referenced this pull request Sep 5, 2026
…ed 2026-08-26

The requested release version 1.10.3 turned out to already be tagged and
published (GitHub release + npm @forgeone/cli@1.10.3, both dated 2026-08-26,
from PR #42). This session's earlier merge of PR #43 into main incorrectly
folded PR #43's new fixes into that same already-released "## [1.10.3]"
CHANGELOG section instead of treating it as immutable history. Split them
back apart: the original 1.10.3 entry (Test/Code fabrication past a pause,
undetected stale pending turn, ambiguous multi-spec resolution, .gitignore
coverage, CI gates) is restored verbatim with its original date, and PR #43's
fixes (LLM-pipeline agent-mode fallback, the critical wrong-feature resume,
the arch-debate data race, and dry-run leaks) now form their own [1.10.4]
section, which is the version actually being tagged and released next.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.

2 participants