Skip to content

Commit aa45919

Browse files
os-warrenclaude
andauthored
test(engine-doubles): add the findOne slice to check:engine-double-contract and adopt assertEngineFindOnePredicate across the re-measured 211-file remainder (#12560)
* test(engine-doubles): adopt assertEngineFindOnePredicate across 212 files / 245 findOne doubles The adoption half of #12068. Discovery was NOT re-derived by hand: the population is `check:engine-double-contract`'s own reported (file, line) answers with a findOne slice installed, so the batch cannot be narrower or wider than what the gate scores. `@objectstack/service-datasource` gains `@objectstack/metadata-core` as a devDependency — the one package in the remainder that depended on neither home of the predicate. Acyclic, measured rather than cited: `turbo run build --filter=@objectstack/service-datasource --dry` exits 0 with zero circular-dependency reports and metadata-core present in the graph. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6HFzyH98W1YaQXhJUJt6o * wip(engine-doubles): recovered uncommitted gate half from a stalled dispatch NOT REVIEWED. The dispatch that wrote this stalled before committing or pushing; this commit exists only so the work survives the container, and the resuming dev is expected to inspect it, not to trust it. Contents as found on disk: the findOne slice added to check-engine-double-contract's SLICES table (assertEngineFindOnePredicate / resolveEngineFindOnePredicate, origin #4419), plus the regenerated baseline and pinned ledgers. No gate run, no test run, and no ablation was performed against it here. * fix(engine-doubles): close the two defects the recovered findOne sweep left, and alias metadata-core in service-datasource Supersedes the "NOT REVIEWED" disclaimer on 88784b7: the gate half and the 211-file adoption below it have now been run, ablated and re-measured. Three things this commit changes, all of them found by running what that commit never ran. 1. TS2345 in service-messaging. `delivery-headers-at-rest.integration.test.ts` passed the fake's `q: unknown` straight into the predicate, whose parameter is `EngineFindOneQueryInput | null | undefined`. vitest never type-checks, so the suite was green and `tsc --noEmit` was red — the one direction a test-only sweep can go wrong invisibly. Cast at the call, matching the sibling `assertEngineUpdateDispatch(d as any, q as any)` pin three lines below it. 2. service-datasource's engine double reached `@objectstack/metadata-core` through `dist/`. `check:test-source-alias` names the repair and refuses the alternative: alias the specifier in the package's own vitest config, never widen the shrink-only registry. A pin resolved through a build artifact is pinned to whatever was last built rather than to the predicate beside it, which is the single failure a contract pin exists to prevent. 3. Import order in that same test file is now load-bearing, and says so. Aliasing metadata-core to source pulls its import graph into the package's resolution domain, which switches on the clocked-window rule for the whole package — and that rule then misreported a file that has paid its `@objectstack/spec/kernel` load at module top since #10120. Cause is a detector defect filed as #12555: the gate's import regex swallows a bare side-effect import whenever an `import … from …` follows it later in the file. Not worked around in the gate — the fix there needs its own `--self-test` cases — so the statement is placed where the detector reads it correctly, with a comment naming the constraint and the card that removes it. --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent b566f83 commit aa45919

217 files changed

Lines changed: 1722 additions & 267 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/core/src/utils/migration-journal.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
assertEngineUpdateDispatch,
2828
type EngineDeleteDispatchInput,
2929
type EngineUpdateDispatchData,
30-
type EngineUpdateDispatchInput,
30+
type EngineUpdateDispatchInput, assertEngineFindOnePredicate,
3131
} from '@objectstack/metadata-core';
3232
import {
3333
runMigrationJournal,
@@ -85,6 +85,7 @@ class FakeEngine {
8585
}
8686

8787
async findOne(objectName: string, query?: { where?: Record<string, unknown> }): Promise<FakeRow | null> {
88+
assertEngineFindOnePredicate(objectName, query);
8889
return (await this.find(objectName, query))[0] ?? null;
8990
}
9091

packages/mcp/src/__tests__/plugin.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { describe, it, expect, vi, beforeEach } from 'vitest';
44
import { MCPServerPlugin } from '../plugin.js';
5+
import { assertEngineFindOnePredicate, type EngineFindOneQueryInput } from '@objectstack/metadata-core';
56

67
// ---------------------------------------------------------------------------
78
// Mock PluginContext
@@ -69,7 +70,7 @@ function createMockMetadataService() {
6970
function createMockDataEngine() {
7071
return {
7172
find: vi.fn(async () => []),
72-
findOne: vi.fn(async () => null),
73+
findOne: vi.fn(async (object: string, query?: EngineFindOneQueryInput) => { assertEngineFindOnePredicate(object, query); return null; }),
7374
insert: vi.fn(),
7475
update: vi.fn(),
7576
delete: vi.fn(),

packages/mcp/src/mcp-stdio-tools.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4141
import { MCPServerRuntime } from './mcp-server-runtime.js';
4242
import { MCPServerPlugin } from './plugin.js';
4343
import type { McpDataBridge } from './mcp-http-tools.js';
44-
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch } from '@objectstack/metadata-core';
44+
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch, assertEngineFindOnePredicate, type EngineFindOneQueryInput } from '@objectstack/metadata-core';
4545

4646
// ---------------------------------------------------------------------------
4747
// A real stdio client: newline-delimited JSON-RPC over the transport's pipes
@@ -503,7 +503,7 @@ describe('#8034 plugin composition: os serve stdio wiring', () => {
503503
}),
504504
aggregate: vi.fn(async () => []),
505505
count: vi.fn(async () => 0),
506-
findOne: vi.fn(async () => null),
506+
findOne: vi.fn(async (object: string, query?: EngineFindOneQueryInput) => { assertEngineFindOnePredicate(object, query); return null; }),
507507
};
508508
}
509509

packages/mcp/src/mcp-write-response-internal-fields.tripwire.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import type { ExecutionContext } from '@objectstack/spec/kernel';
4646
import type { IDataEngine, IMetadataService } from '@objectstack/spec/contracts';
4747
import { omitInternalFieldsFromWriteResponse } from '@objectstack/core';
4848
import { createStdioDataBridge } from './stdio-data-bridge.js';
49-
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch } from '@objectstack/metadata-core';
49+
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch, assertEngineFindOnePredicate, type EngineFindOneQueryInput } from '@objectstack/metadata-core';
5050

5151
/** The value that must NEVER appear in any MCP response. */
5252
const SENTINEL = 'INTERNAL-SENTINEL-8497-NEVER-SERIALIZED';
@@ -81,7 +81,7 @@ function makeSentinelEngine(): IDataEngine {
8181
});
8282
return {
8383
find: vi.fn(async () => [storedRow()]),
84-
findOne: vi.fn(async () => storedRow()),
84+
findOne: vi.fn(async (object: string, query?: EngineFindOneQueryInput) => { assertEngineFindOnePredicate(object, query); return storedRow(); }),
8585
insert: vi.fn(async (_o: string, data: Record<string, unknown>) =>
8686
writtenRow((data?.id as string) ?? 'new-1', data)),
8787
update: vi.fn(async (_o: string, data: Record<string, unknown>, options?: any) => {

packages/mcp/src/plugin.record-resource-exposure.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import type { IMetadataService } from '@objectstack/spec/contracts';
5050
import type { MCPServerRuntime } from './mcp-server-runtime.js';
5151
import { MCPServerPlugin } from './plugin.js';
5252
import { enforceApiExposure, GATED_ACTIONS, type McpExposureError } from './stdio-data-bridge.js';
53-
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch } from '@objectstack/metadata-core';
53+
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch, assertEngineFindOnePredicate, type EngineFindOneQueryInput } from '@objectstack/metadata-core';
5454

5555
// ---------------------------------------------------------------------------
5656
// A real stdio client: newline-delimited JSON-RPC over the transport's pipes
@@ -172,7 +172,7 @@ function fakeObjectQL() {
172172
}),
173173
aggregate: vi.fn(async () => []),
174174
count: vi.fn(async () => 0),
175-
findOne: vi.fn(async () => null),
175+
findOne: vi.fn(async (object: string, query?: EngineFindOneQueryInput) => { assertEngineFindOnePredicate(object, query); return null; }),
176176
};
177177
}
178178

packages/mcp/src/stdio-data-bridge.exposure.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { DATA_ACTION_TO_API_OPERATION } from '@objectstack/spec/data';
3939
import type { ExecutionContext } from '@objectstack/spec/kernel';
4040
import type { IDataEngine, IMetadataService } from '@objectstack/spec/contracts';
4141
import { createStdioDataBridge, GATED_ACTIONS, type McpExposureError } from './stdio-data-bridge.js';
42+
import { assertEngineFindOnePredicate, type EngineFindOneQueryInput } from '@objectstack/metadata-core';
4243

4344
// ---------------------------------------------------------------------------
4445
// Doubles
@@ -54,7 +55,7 @@ import { createStdioDataBridge, GATED_ACTIONS, type McpExposureError } from './s
5455
function makeEngine(rows: Array<Record<string, unknown>> = [{ id: 'r1', title: 'row' }]) {
5556
return {
5657
find: vi.fn(async () => rows),
57-
findOne: vi.fn(async () => rows[0] ?? null),
58+
findOne: vi.fn(async (object: string, query?: EngineFindOneQueryInput) => { assertEngineFindOnePredicate(object, query); return rows[0] ?? null; }),
5859
insert: vi.fn(),
5960
update: vi.fn(),
6061
delete: vi.fn(),

packages/mcp/src/stdio-data-bridge.not-found.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ import { describe, it, expect, vi } from 'vitest';
2323
import type { ExecutionContext } from '@objectstack/spec/kernel';
2424
import type { IDataEngine, IMetadataService } from '@objectstack/spec/contracts';
2525
import { createStdioDataBridge } from './stdio-data-bridge.js';
26+
import { assertEngineFindOnePredicate, type EngineFindOneQueryInput } from '@objectstack/metadata-core';
2627

2728
/** An engine that resolves NO row for any id — every by-id write is a miss. */
2829
function makeEmptyEngine() {
2930
return {
3031
find: vi.fn(async () => []),
31-
findOne: vi.fn(async () => null),
32+
findOne: vi.fn(async (object: string, query?: EngineFindOneQueryInput) => { assertEngineFindOnePredicate(object, query); return null; }),
3233
insert: vi.fn(),
3334
update: vi.fn(),
3435
delete: vi.fn(),

packages/metadata-protocol/src/migrations/recorded-by-sentinel.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { runMigrationJournal, readRunJournal } from '@objectstack/core';
2929
// package both sides already depend on, which is what makes this line legal.
3030
import {
3131
assertEngineDeleteDispatch,
32-
assertEngineUpdateDispatch,
32+
assertEngineUpdateDispatch, assertEngineFindOnePredicate,
3333
} from '@objectstack/metadata-core';
3434
import {
3535
createRecordedBySentinelPlan,
@@ -77,6 +77,7 @@ class FakeEngine {
7777
}
7878

7979
async findOne(objectName: string, query?: { where?: Record<string, unknown> }): Promise<FakeRow | null> {
80+
assertEngineFindOnePredicate(objectName, query);
8081
return (await this.find(objectName, query))[0] ?? null;
8182
}
8283

packages/metadata-protocol/src/protocol-publish-drafts-advisories.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
*/
3636

3737
import { describe, expect, it } from 'vitest';
38-
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch } from '@objectstack/metadata-core';
38+
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch, assertEngineFindOnePredicate } from '@objectstack/metadata-core';
3939
import { ObjectStackProtocolImplementation } from './protocol.js';
4040

4141
interface Row {
@@ -117,6 +117,7 @@ function makeStubEngine() {
117117

118118
const engine: any = {
119119
async findOne(table: string, opts: { where: Record<string, unknown> }) {
120+
assertEngineFindOnePredicate(table, opts);
120121
if (table === 'sys_metadata_history') {
121122
return historyRows.find((h) => matchesHistory(h, opts.where)) ?? null;
122123
}

packages/metadata-protocol/src/protocol-publish-drafts-closure.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
5656
// The producer's OWN write-verb dispatch decisions, so the fake engine below
5757
// cannot accept a call ObjectQL refuses. From `@objectstack/metadata-core`,
5858
// never from `@objectstack/objectql` — that import would close a cycle.
59-
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch } from '@objectstack/metadata-core';
59+
import { assertEngineDeleteDispatch, assertEngineUpdateDispatch, assertEngineFindOnePredicate } from '@objectstack/metadata-core';
6060
import { ObjectStackProtocolImplementation } from './protocol.js';
6161

6262
interface Row {
@@ -155,6 +155,7 @@ function makeStubEngine(options?: { liveObjects?: unknown[]; livePermissions?: u
155155

156156
const engine: any = {
157157
async findOne(table: string, opts: { where: Record<string, unknown> }) {
158+
assertEngineFindOnePredicate(table, opts);
158159
if (table === 'sys_metadata_history') {
159160
return historyRows.find((h) => matchesHistory(h, opts.where)) ?? null;
160161
}

0 commit comments

Comments
 (0)