Two product defects surfaced by workspace-e2e's remaining failures.
1. A merge-boundary fence silently did not apply. captureWorkspaceReviewEvidence
computes a repository's file list over baseCommitSha..<resolved task branch>,
but computeReviewDiffFingerprint hardcoded baseRef..HEAD. For a workspace
entry whose checkout sits on the integration branch those are different
ranges, so the fingerprint did not describe the files captured beside it: a
diverged checkout hard-failed an approved repository as content-changed,
and a checkout at the base produced an empty diff -> undefined fingerprint ->
the repo dropped out of mergeBoundaryFingerprints, so BOTH the
approval-missing and content-changed fences stopped applying to it at all.
computeReviewDiffFingerprint now takes an optional headRef; workspace
evidence passes the resolved task branch. The singular-review caller, whose
worktree IS the branch, keeps the ambient HEAD default.
2. Land intents were recorded and resolved under different conditions.
landOneRepo records an intent only when ctx.workspaceLand is set, which
landWorkspaceTask passes only for remote targets, but the resolve side was
gated on durableLandLease alone. A local-only land therefore resolved an
intent that was never recorded, got "missing", and failed a fully-landed
repo as a partial land AFTER its integration ref had advanced. Resolve now
uses the same condition as record.
The approveWorkspaceReview helper's "reviewStep called exactly once" constant
only held because defect 1 suppressed a repository; it now derives the expected
count from the same production capture the review loop uses.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>