Conversation
…g forever FN-9369 made the `post-merge-verification` optional group a REQUIRED gate, and `upgradeLegacyCodingPostMergeVerificationStepIds()` auto-migrates older built-in coding tasks onto it, so a task can acquire a gate it never enabled by hand. That gate is a GRAPH post-merge hop. `workflow-graph-executor` only walks it from inside `runLegacyMergeSeam` (`postMergeEntryNodeIds` -> `walk(entryId)`), i.e. while the `merge` node is still executing. Once the merge seam has returned, every later `finalizeProvenAutoMergeTask` call finds the gate unreported and returns `blocked`, and nothing re-entered the graph at the post-merge node. Measured on a local checkout with no upstream CI: a task with real commits landed (`mergeDetails.mergeConfirmed`, mergedAt recorded) stayed in `in-review` forever while the engine logged `Auto-merge finalization deferred ... required post-merge evidence gate 'post-merge-verification' has not reported` every 15s. The gate's own prompt demands post-landing Full Suite / shard / timing evidence that such a repository can never produce, so the block was terminal by construction. The guard is right and is kept: no evidence, no completion. What was missing is who owns RUNNING the gate. Finalization now schedules the unreported gate as a runnable continuation before deferring, so the deadlock resolves instead of silently parking the card. The write goes through `replaceActiveTaskWorkflowContinuation` because a bare upsert targets a different constraint than the one-active-continuation index and raises when a row already exists — the failure mode that previously deadlocked the board. The advisory pre-check skips a gate that already has a live continuation, and a write failure is logged rather than thrown, so a refused finalization never becomes a crash. No existing open PR in the fork touches `confirmed-merge-reconciliation.ts`, `workflow-optional-steps.ts`, `builtin-coding-workflow-ir.ts` or `builtin-post-merge-group.ts`; PR #26 (fm/fusion-noop-merge) addresses a different defect (in-review cards that committed nothing) and does not apply to cards with real commits. Verified: 2198 engine tests pass, 17 files fail identically on unmodified origin/main (pre-existing, not a regression), typecheck and the full static gate clean.
ThreatCrush Security Scan4589 finding(s) HIGH/CRITICAL: 43 | MEDIUM: 4035 | LOW: 511
…and 4539 more. Full results in the Security tab. Snippets are redacted; ThreatCrush never prints matched credential material. |
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.
fix(engine): re-arm an unreported post-merge gate instead of deferring forever
FN-9369 made the
post-merge-verificationoptional group a REQUIRED gate, andupgradeLegacyCodingPostMergeVerificationStepIds()auto-migrates older built-incoding tasks onto it, so a task can acquire a gate it never enabled by hand.
That gate is a GRAPH post-merge hop.
workflow-graph-executoronly walks it frominside
runLegacyMergeSeam(postMergeEntryNodeIds->walk(entryId)), i.e. whilethe
mergenode is still executing. Once the merge seam has returned, every laterfinalizeProvenAutoMergeTaskcall finds the gate unreported and returnsblocked,and nothing re-entered the graph at the post-merge node.
Measured on a local checkout with no upstream CI: a task with real commits landed
(
mergeDetails.mergeConfirmed, mergedAt recorded) stayed inin-reviewforeverwhile the engine logged
Auto-merge finalization deferred ... required post-merge evidence gate 'post-merge-verification' has not reportedevery 15s. The gate's ownprompt demands post-landing Full Suite / shard / timing evidence that such a
repository can never produce, so the block was terminal by construction.
The guard is right and is kept: no evidence, no completion. What was missing is
who owns RUNNING the gate. Finalization now schedules the unreported gate as a
runnable continuation before deferring, so the deadlock resolves instead of
silently parking the card.
The write goes through
replaceActiveTaskWorkflowContinuationbecause a bareupsert targets a different constraint than the one-active-continuation index and
raises when a row already exists — the failure mode that previously deadlocked the
board. The advisory pre-check skips a gate that already has a live continuation,
and a write failure is logged rather than thrown, so a refused finalization never
becomes a crash.
No existing open PR in the fork touches
confirmed-merge-reconciliation.ts,workflow-optional-steps.ts,builtin-coding-workflow-ir.tsorbuiltin-post-merge-group.ts; PR #26 (fm/fusion-noop-merge) addresses a differentdefect (in-review cards that committed nothing) and does not apply to cards with
real commits.
Verified: 2198 engine tests pass, 17 files fail identically on unmodified
origin/main (pre-existing, not a regression), typecheck and the full static gate
clean.
Por que nenhuma opcao de contorno resolveria
Desativar
graphNativePostMergeou remover o step por task deixa o card passar, mas o defeitovolta na proxima task que o
upgradeLegacyCodingPostMergeVerificationStepIds()migrar. Estacorrection ataca a lacuna que faz o gate ser inalcancavel, nao o sintoma.
Teste que prova o defeito
post-merge-gate-scheduling.test.tsfalha na base (upsertWorkflowWorkItemchamado 0 vezes) epassa com a correcao. Ele fixa os tres contratos:
runnable(o bloqueio continua, mas deixa de ser terminal)O teste existente
confirmed-merge-must-finalize.test.ts, que fixa "blocks until the enabledpost-merge gate approves", continua passando sem alteracao.
Verificacao
pnpm --filter @fusion/engine typechecklimpopnpm test:gate:staticcompleto limpo (incluicheck-changeset-format,check-no-test-timeout-appeasement,check-no-comment-assertions-in-tests)origin/mainsem esta mudanca (baseline rodada em worktreelimpo): sao falhas pre-existentes do repo, nao regressao