Skip to content

MSW contract suite validates an obsolete LatestResult schema #255

Description

@MicroMilo

Summary

CliLatestResult requires verdict and executionStatus and replaces the old count-object summary with a semantic string. The MSW fixtures omit both required fields, retain the old object summary, and the strict P4 contract validator explicitly validates that obsolete shape.

Impact: MSW-backed tests exercise a result object that real command code no longer supports. Text rendering produces — (no verdict yet), executionStatus: undefined, and summary: [object Object], while the purported strict OpenAPI contract test remains false-green by requiring the obsolete object summary and omitting the new required keys.

Code path

Checked against current main at commit 60d55e47883e924ff1a5f0ab1fe67a25bc3b0877.

  • src/commands/test.ts:281-294
  • test/mock-backend/fixtures.ts:266-281
  • test/contract/p4-schema.test.ts:73-90
  • test/contract/p4-schema.test.ts:181-190
  • src/commands/test.ts:9747-9760

Steps to reproduce

Validation level: current HEAD supplemental dynamic witness reproduced.

node --no-warnings --experimental-strip-types -e "import('./test/mock-backend/fixtures.ts').then(({latestResultFailedFixture}) => { const expected=['verdict','executionStatus']; const missing=expected.filter(k => !(k in latestResultFailedFixture)); console.log(JSON.stringify({missing,summaryType:typeof latestResultFailedFixture.summary,rendered:{verdict:latestResultFailedFixture.verdict ?? '— (no verdict yet)',executionStatus:String(latestResultFailedFixture.executionStatus),summary:String(latestResultFailedFixture.summary)}})); process.exit(missing.length===2 && typeof latestResultFailedFixture.summary==='object' ? 1 : 0); })"

Observed output:

{"missing":["verdict","executionStatus"],"summaryType":"object","rendered":{"verdict":"— (no verdict yet)","executionStatus":"undefined","summary":"[object Object]"}}

Neighboring control:

node --no-warnings --experimental-strip-types --experimental-loader ./.cqpt-run/source-loader.mjs -e "import('./src/lib/dry-run/samples.ts').then(({findSample}) => { const value=findSample('GET','/tests/t/result').body(); const expected=['verdict','executionStatus']; const missing=expected.filter(k => !(k in value)); console.log(JSON.stringify({missing,summaryType:typeof value.summary,rendered:{verdict:value.verdict ?? '— (no verdict yet)',executionStatus:String(value.executionStatus),summary:String(value.summary)}})); process.exit(missing.length===0 && typeof value.summary==='string' ? 0 : 1); })"

Control output:

{"missing":[],"summaryType":"string","rendered":{"verdict":"failed","executionStatus":"completed","summary":"Failed (assertion) on step 5: expected cart badge to show 1 item, but it was empty."}}

Expected behavior

The documented/source-grounded contract should hold without the drift described above.

Actual behavior

The mock result endpoint and its strict contract test remain pinned to the retired LatestResult schema.

Existing coverage

I checked the current issue and PR lists for overlapping titles/root-cause keywords before filing this. I did not find an item covering this same root cause.

Suggested fix

Migrate all mock LatestResult fixtures and the strict P4 validator to verdict, executionStatus, and string summary.

Suggested tests

  • Add a regression test for the reproduction above.
  • Add a neighboring control assertion so the intended non-bug path remains covered.

Submitted with Codex.

Metadata

Metadata

Assignees

Labels

in-progressAssigned and actively being worked on

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions