Skip to content

fix(ship): agent-mode arch debate, --until, false-green/noisy gates, and hook GIT_DIR isolation (for v1.10.8) - #47

Merged
teragrid merged 2 commits into
mainfrom
fix/agent-mode-gates-v1.10.8
Sep 21, 2026
Merged

teragrid merged 2 commits into
mainfrom
fix/agent-mode-gates-v1.10.8

Conversation

@teragrid

Copy link
Copy Markdown
Owner

What

Fixes and one addition found by driving forge ship --agent-mode through the spec and arch checkpoints of a real feature on a Next.js/Supabase + Python two-repo system, plus a hook bug found while pushing this very change.

Fixed

  • arch debate discarded answers (bug). In agent mode checkArch wrote arch.md with (no concerns raised) for all six roles while the first debate turn was still owed. The next run hit the "arch.md exists" shortcut, so the debate never resumed and the submitted answer was lost. It now pauses without writing and asks each role in turn.
  • arch prompt vs adr-quality-gate. The prompt never asked for alternatives; the gate fails an ADR with fewer than two. The prompt now asks for an Alternatives Considered section.
  • ship false green. ship reported ok plus "spec-vs-code audit found no blocking gaps" on a branch with no source changes. It now warns ("nothing to ship") and withholds the claim; unknown git state keeps the old behaviour (new gitservice.ChangedFilesOnBranch).
  • test checkpoint count. Reported the whole repo's test-file count. It now reports the feature's own tests and warns when it has none.
  • agent-mode banner no longer says YOLO when --yolo was not passed.
  • unverified-file-reference check flagged cross-repo citations as hallucinated. forge.yml related_repos now resolves them and lists sibling repos in the workspace context.
  • workspace context detects frameworks (Next.js, Supabase, TypeScript, ...) from package.json / tsconfig.json / supabase/; the feature being planned is no longer listed as an existing spec.
  • failure history in spec prompts is scoped to the current feature (recent others only) and de-duplicated.
  • pre-push hook / gitservice inherited git's exported GIT_DIR. Tests that shell out to git in a temp dir therefore ran against the repository being pushed: they committed fixtures onto the pushed branch, force-renamed branches (overwriting main) and rewrote .git/config (core.bare, user.name). The hook now unsets the repo-pointing variables, and gitservice no longer passes them to the git processes it starts. Regression test verified to fail without the change; the fixed hook was also exercised end to end against a throwaway clone and remote (all 13 stages green, refs and config unchanged).

Added

  • forge ship --until <checkpoint> — stop after the named checkpoint so spec/arch can be reviewed before test/breakdown/code exist.

Deliberately not changed

  • self-review-gate reporting UNVERIFIED on a first run (its docstring says scanning zero files is not a clean bill of health).

Verification

  • New regression tests for every change; the arch-debate and GIT_DIR tests were confirmed to fail without their fixes.
  • go test ./... — 77 packages ok; golangci-lint clean on the changed packages; all 13 pre-push stages pass.
  • End to end with the built binary in a scratch repo: --until arch asked all six debate roles in turn, kept all six answers (0 placeholders), and wrote no test/breakdown/code/ship stubs.

🤖 Generated with Claude Code

vietking and others added 2 commits September 21, 2026 02:14
…es found dogfooding on a two-repo project

Found by driving `forge ship --agent-mode` through the spec and arch
checkpoints of a real feature on a Next.js/Supabase + Python two-repo system.

Fixed
- arch: in agent mode checkArch wrote arch.md (with "(no concerns raised)"
  placeholders for every role) while the first debate turn was still owed. The
  next run hit the "arch.md exists" shortcut, so the debate never resumed and
  the submitted answer was discarded. It now pauses without writing and asks
  each of the six roles in turn.
- arch: the generation prompt never asked for alternatives although
  adr-quality-gate fails an ADR with fewer than two; it now does.
- ship: reported status ok, with a "spec-vs-code audit found no blocking
  gaps" evidence line, on a branch with no source changes. It now warns
  ("nothing to ship") and withholds the audit claim. Unknown git state keeps
  the old behaviour.
- test: the detail reported the whole repository's test-file count
  ("671 test file(s) found"). It now reports the feature's own tests and warns
  when it has none.
- agent-mode banner said "[YOLO — approval gates disabled]" although --yolo
  was never passed; it now describes agent mode.
- unverified-file-reference check flagged every cross-repo citation as
  hallucinated. forge.yml `related_repos` now resolves them and lists the
  sibling repos in the workspace context.
- workspace context reported only "Node.js" / "GitHub Actions CI" for a
  Next.js + Supabase + TypeScript project; it now detects frameworks from
  package.json, tsconfig and supabase/. The feature being planned is no longer
  listed as an existing spec once its directory exists.
- failure history injected into a spec prompt included nine-day-old failures
  of unrelated features and repeated identical lines; it is now scoped to the
  current feature (recent others only) and de-duplicated.

Added
- `forge ship --until <checkpoint>`: stop after the named checkpoint so spec
  and arch can be reviewed before test/breakdown/code exist.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Nguyen Quang Trung <likeawind510@gmail.com>
…T_DIR

git exports GIT_DIR (and related variables) to hooks. The pre-push gate runs
`go test ./...`, and every test or tool that shells out to git in a temp dir
(`git init`, `commit`, `branch -M`, `checkout -b`) therefore operated on the
repository being pushed: it committed fixtures onto the branch, force-renamed
branches (overwriting `main`) and rewrote .git/config (core.bare, user.name).
Seen on a real push from a linked worktree.

- .githooks/pre-push unsets the repo-pointing variables so every stage, and
  everything it spawns, resolves the repository from the working directory.
- gitservice no longer passes them to the git processes it starts: a Service is
  opened on an explicit root and must answer for that root, not for whichever
  repository the parent environment names. Regression test verified to fail
  without the change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Nguyen Quang Trung <likeawind510@gmail.com>
@teragrid
teragrid merged commit beccd66 into main Sep 21, 2026
26 checks passed
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