fix(tests): main red — the IR fallback is a BRANDED COPY, so identity can't hold (#2836)

## Red on main

```
workflow-ir-resolver > resolveWorkflowIrForTask > falls back to the built-in default when the definition is missing
workflow-ir-resolver > resolveWorkflowIrById  > falls back to the canonical IR for an unknown built-in id

AssertionError: expected { version: 'v2', …(6), …(1) } to be { version: 'v2', …(6) }
  Received: serializes to the same string
  Compared values have no visual difference.
```

That message is the signature of an **identity-only** break, and that is
exactly what it is.

## Why identity can never hold again

Both asserted `toBe` against the exported builtin constant. **#2815**
added `markFellBack`:

```ts
function markFellBack(ir: WorkflowIr): WorkflowIr {
  const copy = { ...ir } as WorkflowIr;
  Object.defineProperty(copy, FELL_BACK_TO_DEFAULT, { value: true, enumerable: false, configurable: true });
  return copy;
}
```

It brands the fallback so a caller can tell a **resolved** workflow from
a **guessed** one — the provenance contract #2618 introduced. Copying
*is* the mechanism, so these two paths cannot return the shared object.

Worth noting: the sibling `toBe` assertions in the same file **still
pass**. The no-selection and throwing-selection paths return the
constant unbranded, so only the two `markFellBack` paths changed — which
is why this presents as two failures rather than five, and why it is a
genuine contract change rather than a blanket refactor.

## Not just loosening to `toEqual`

Swapping `toBe` → `toEqual` alone would delete a real assertion. The
**brand is asserted too**, via the public provenance API rather than by
reaching for the private symbol:

```ts
expect(ir).toEqual(BUILTIN_STEPWISE_FINAL_REVIEW_CODING_WORKFLOW_IR);
const provenance = await resolveWorkflowIrForTaskWithProvenance(store, "t1");
expect(provenance.source).toBe("default");
```

This is **stronger** than the identity check it replaces:

| mutation | result |
|---|---|
| fallback no longer branded | **fails** — `expected 'selection' to be
'default'` |
| fallback returns a different IR entirely | **fails** structurally |

The first is the case the old `toBe` could not articulate: an unbranded
fallback still equals the constant structurally, so a caller asking
*"was this actually resolved?"* would get **yes for a guess** —
precisely the lie #2815 exists to prevent.

Core **4792 passed / 0 failed** (was 2 failed) · gate **732 green** ·
lint clean. Test-only; the resolver is restored clean after the
mutations.

## How it was found

Pre-flighting **#2822, #2819, #2823 and #2818** merged-with-main. All
four reported the *same two* failures — the signature of an inherited
red rather than four independent regressions. Confirmed directly on
`origin/main`. Each of those four is otherwise green (engine 11003
passed on all of them); I have noted that on the PRs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-07-30 14:20:18 -07:00
committed by GitHub
parent 2c24966d0c
commit 4c5080c1cf

View File

@@ -5,6 +5,7 @@ import type { WorkflowIr } from "../workflow-ir-types.js";
import {
resolveWorkflowIrForTask,
resolveWorkflowIrById,
resolveWorkflowIrForTaskWithProvenance,
} from "../workflow-ir-resolver.js";
/** A minimal custom IR distinguishable from the built-in default. */
@@ -73,7 +74,27 @@ describe("resolveWorkflowIrForTask", () => {
defs: { "wf-gone": undefined },
});
const ir = await resolveWorkflowIrForTask(store, "t1");
expect(ir).toBe(BUILTIN_STEPWISE_FINAL_REVIEW_CODING_WORKFLOW_IR);
/*
FNXC:WorkflowIrResolver 2026-07-31-08:10:
STRUCTURAL, not identity — the fallback is deliberately a BRANDED COPY now.
This asserted `toBe`, i.e. the very object exported as the builtin constant. #2815 added
`markFellBack`, which returns `{ ...ir }` carrying a non-enumerable symbol so a caller can tell a
RESOLVED workflow from a GUESSED one (the provenance contract #2618 introduced). Copying is the
mechanism, so identity here can never hold again — the test failed with "serializes to the same
string / Compared values have no visual difference", which is exactly what an identity-only break
looks like.
Loosening `toBe` to `toEqual` alone would lose a real assertion, so the brand is asserted too, via
the public provenance API rather than by reaching for the private symbol. That is the behaviour
#2815 exists to provide, and it is stronger than the identity check it replaces: an accidental
return of the shared constant would now fail HERE (source would still be "default", but a future
change dropping the brand would break `didFallBackToDefault` consumers silently otherwise).
*/
expect(ir).toEqual(BUILTIN_STEPWISE_FINAL_REVIEW_CODING_WORKFLOW_IR);
const provenance = await resolveWorkflowIrForTaskWithProvenance(store, "t1");
expect(provenance.source).toBe("default");
expect(provenance.ir).toEqual(BUILTIN_STEPWISE_FINAL_REVIEW_CODING_WORKFLOW_IR);
});
it("falls back to the default when there is no selection", async () => {
@@ -130,7 +151,8 @@ describe("resolveWorkflowIrById", () => {
it("falls back to the canonical IR for an unknown built-in id", async () => {
const store = makeStore({});
const ir = await resolveWorkflowIrById(store, "builtin:missing");
expect(ir).toBe(BUILTIN_STEPWISE_FINAL_REVIEW_CODING_WORKFLOW_IR);
/* Structural for the same reason as above: an unknown builtin id takes the branded-copy fallback. */
expect(ir).toEqual(BUILTIN_STEPWISE_FINAL_REVIEW_CODING_WORKFLOW_IR);
expect(store.getWorkflowDefinition).not.toHaveBeenCalled();
});