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:
@@ -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();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user