feat(invariants): implement package runtime checks

This commit is contained in:
Tianyi Cui
2026-07-20 00:38:37 +08:00
parent 36e99e737b
commit 941b0411d8
125 changed files with 2317 additions and 1161 deletions
@@ -1,10 +1,20 @@
import { describe, expect, it, vi } from 'vitest'
import { Context, Service } from 'cordis'
import InvariantService, { InvariantError, type Config } from '@deepseek-ai/dsh-invariants'
import InvariantService, {
InvariantError,
assertInvariant,
observePluginInvariant,
observeServiceInvariant,
serviceShapeViolation,
type Config,
type InvariantInstaller,
type PluginInvariantContract,
} from '@deepseek-ai/dsh-invariants'
declare module 'cordis' {
interface Context {
invariantProbe: InvariantProbeService
watchedInvariantProbe: WatchedInvariantProbeService
}
interface Events {
@@ -18,6 +28,12 @@ class InvariantProbeService extends Service {
}
}
class WatchedInvariantProbeService extends Service {
constructor(ctx: Context) {
super(ctx, 'watchedInvariantProbe')
}
}
interface RuntimeRegistration extends PromiseLike<() => void> {
(): void | Promise<void>
}
@@ -264,3 +280,207 @@ describe('InvariantService lifecycle', () => {
expect(() => service.register('@deepseek-ai/dsh-session', () => {})).toThrow(/inactive/i)
})
})
describe('package-owned invariant helpers', () => {
async function registerInstaller(
ctx: Context,
packageName: string,
installer: InvariantInstaller,
): Promise<() => void> {
const registration = runtimeRegistration(ctx.invariants.register(packageName, installer))
const dispose = await Promise.resolve(registration)
return dispose
}
function effectPlugin(options: {
name?: string
inject?: string[]
effect?: string
service?: string
} = {}) {
return {
name: options.name ?? 'effect-probe',
inject: options.inject ?? [],
apply(ctx: Context) {
if (options.service !== undefined) ctx.provide(options.service, {})
if (options.effect !== undefined) {
ctx.effect(() => {
ctx.effect(() => () => {}, `${options.effect}.child`)
return () => {}
}, options.effect)
}
},
}
}
async function expectPluginViolation(
contract: PluginInvariantContract,
plugin: ReturnType<typeof effectPlugin>,
message: RegExp,
): Promise<void> {
const { ctx } = await setup()
await registerInstaller(ctx, `@deepseek-ai/${contract.name}`, (child, fail) => {
observePluginInvariant(child, fail, contract)
})
await expect(Promise.resolve(ctx.plugin(plugin))).rejects.toThrow(message)
}
it('checks existing and later plugin fibers, including nested effects and alternatives', async () => {
const { ctx } = await setup()
await ctx.plugin(InvariantProbeService)
const plugin = effectPlugin({
inject: ['invariantProbe'],
effect: 'probe.effect',
service: 'pluginProbe',
})
await ctx.plugin(plugin)
const validated = vi.fn(() => undefined)
await registerInstaller(ctx, '@deepseek-ai/dsh-existing-probe', (child, fail) => {
observePluginInvariant(child, fail, {
plugin,
name: 'effect-probe',
inject: ['invariantProbe'],
effects: [['missing.effect', 'probe.effect.child']],
services: ['pluginProbe'],
validate: validated,
})
})
expect(validated).toHaveBeenCalledOnce()
const later = effectPlugin({ name: 'later-probe', effect: 'later.effect' })
await registerInstaller(ctx, '@deepseek-ai/dsh-later-probe', (child, fail) => {
observePluginInvariant(child, fail, {
plugin: later,
name: 'later-probe',
effects: ['later.effect'],
})
})
await ctx.plugin(later)
})
it('matches package plugins by Cordis name without importing their callback', async () => {
const { ctx } = await setup()
const plugin = {
name: 'name-only-probe',
apply(pluginCtx: Context) {
pluginCtx.effect(() => () => {}, 'name-only.effect')
pluginCtx.inject([], () => {})
},
}
await registerInstaller(ctx, '@deepseek-ai/dsh-name-only-probe', (child, fail) => {
observePluginInvariant(child, fail, {
name: 'name-only-probe',
effects: ['name-only.effect'],
})
})
await ctx.plugin(plugin)
})
it('rejects a contract that does not identify a plugin', async () => {
const { ctx } = await setup()
const registration = runtimeRegistration(ctx.invariants.register('@deepseek-ai/dsh-invalid-plugin', (child, fail) => {
observePluginInvariant(child, fail, {
plugin: {} as never,
name: 'invalid-plugin',
})
}))
await expect(Promise.resolve(registration)).rejects.toThrow(/does not identify a Cordis plugin/)
})
it('rejects wrong plugin names, missing injections, effects, services, and custom checks', async () => {
const wrongName = effectPlugin({ name: 'actual-name', effect: 'probe.effect' })
await expectPluginViolation({
plugin: wrongName,
name: 'expected-name',
}, wrongName, /plugin name must be "expected-name"/)
const missingInjection = effectPlugin({ effect: 'probe.effect' })
await expectPluginViolation({
plugin: missingInjection,
name: 'effect-probe',
inject: ['missingService'],
}, missingInjection, /must inject "missingService"/)
const missingEffect = effectPlugin()
await expectPluginViolation({
plugin: missingEffect,
name: 'effect-probe',
effects: [['first.effect', 'second.effect']],
}, missingEffect, /must own effect "first.effect" or "second.effect"/)
const missingService = effectPlugin({ effect: 'probe.effect' })
await expectPluginViolation({
plugin: missingService,
name: 'effect-probe',
services: ['missingService'],
}, missingService, /must provide service "missingService"/)
const invalidCustom = effectPlugin({ effect: 'probe.effect' })
await expectPluginViolation({
plugin: invalidCustom,
name: 'effect-probe',
validate: () => 'custom plugin contract failed',
}, invalidCustom, /custom plugin contract failed/)
})
it('checks existing and future service implementations while ignoring unrelated changes', async () => {
const existing = await setup()
await existing.ctx.plugin(WatchedInvariantProbeService)
await registerInstaller(existing.ctx, '@deepseek-ai/dsh-existing-service', (child, fail) => {
observeServiceInvariant(child, fail, 'watchedInvariantProbe', value => (
value instanceof WatchedInvariantProbeService ? undefined : 'wrong watched service'
))
})
const future = await setup()
await registerInstaller(future.ctx, '@deepseek-ai/dsh-future-service', (child, fail) => {
observeServiceInvariant(child, fail, 'watchedInvariantProbe', value => (
value instanceof WatchedInvariantProbeService ? undefined : 'wrong watched service'
))
})
await future.ctx.plugin(InvariantProbeService)
await future.ctx.plugin(WatchedInvariantProbeService)
const invalid = await setup()
await registerInstaller(invalid.ctx, '@deepseek-ai/dsh-invalid-service', (child, fail) => {
observeServiceInvariant(child, fail, 'watchedInvariantProbe', () => 'wrong watched service')
})
await expect(Promise.resolve(invalid.ctx.plugin(WatchedInvariantProbeService)))
.rejects.toThrow(/wrong watched service/)
})
it('reports synchronous package assertions through the bound failure reporter', async () => {
const { ctx } = await setup()
const valid = await registerInstaller(ctx, '@deepseek-ai/dsh-valid-assertion', (_child, fail) => {
assertInvariant(fail, true, 'must stay true')
})
valid()
const invalid = runtimeRegistration(ctx.invariants.register('@deepseek-ai/dsh-invalid-assertion', (_child, fail) => {
assertInvariant(fail, false, 'must stay true')
}))
await expect(Promise.resolve(invalid)).rejects.toThrow(/must stay true/)
})
it('accepts structural service implementations and test doubles', () => {
expect(serviceShapeViolation({ kind: 'probe', run() {} }, {
methods: ['run'],
stringProperties: ['kind'],
})).toBeUndefined()
expect(serviceShapeViolation(Object.assign(() => {}, { run() {} }), {
methods: ['run'],
})).toBeUndefined()
})
it.each([
{ value: null, message: 'service implementation must be an object' },
{ value: 42, message: 'service implementation must be an object' },
{ value: {}, message: 'service implementation must expose method "run"' },
{ value: { run() {}, kind: '' }, message: 'service implementation must expose non-empty string "kind"' },
])('rejects invalid structural service implementations: $message', ({ value, message }) => {
expect(serviceShapeViolation(value, {
methods: ['run'],
stringProperties: ['kind'],
})).toBe(message)
})
})