fix(invariants): assert runtime relationships, not API shapes

This commit is contained in:
Tianyi Cui
2026-07-20 19:34:19 +08:00
parent 1254c07025
commit 1145ee5fc3
124 changed files with 2923 additions and 2334 deletions

View File

@@ -1,27 +1,24 @@
/** Package-owned runtime contract checks for `@deepseek-ai/dsh-subagent-acp`. @module @deepseek-ai/dsh-subagent-acp/invariant */
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-subagent-acp`.
* @module @deepseek-ai/dsh-subagent-acp/invariant
*/
/* jscpd:ignore-start */
import type { Context } from 'cordis'
import { observePluginInvariant, type InvariantInstaller } from '@deepseek-ai/dsh-invariants'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-acp'
/** Cordis companion plugin name. */
export const name = 'subagent-acp-invariant'
/** Services required before the companion can register. */
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/** Install checks for this package's active plugin fibers. */
const install: InvariantInstaller = (ctx, fail) => {
observePluginInvariant(ctx, fail, {
name: 'subagent-acp',
inject: [
'subagents',
],
effects: [
'subagents.registerProvider()',
],
})
}
/**
* No runtime invariant: this package exposes no independent event sequence or mutable data relation
* beyond contracts enforced at its owning seam.
*/
const install: InvariantInstaller = () => {}
/**
* Register this package's invariant companion.
@@ -30,3 +27,4 @@ const install: InvariantInstaller = (ctx, fail) => {
*/
export const apply = (ctx: Context): Promise<() => void> =>
Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install))
/* jscpd:ignore-end */

View File

@@ -1,27 +1,24 @@
/** Package-owned runtime contract checks for `@deepseek-ai/dsh-subagent-fork`. @module @deepseek-ai/dsh-subagent-fork/invariant */
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-subagent-fork`.
* @module @deepseek-ai/dsh-subagent-fork/invariant
*/
/* jscpd:ignore-start */
import type { Context } from 'cordis'
import { observePluginInvariant, type InvariantInstaller } from '@deepseek-ai/dsh-invariants'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-fork'
/** Cordis companion plugin name. */
export const name = 'subagent-fork-invariant'
/** Services required before the companion can register. */
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/** Install checks for this package's active plugin fibers. */
const install: InvariantInstaller = (ctx, fail) => {
observePluginInvariant(ctx, fail, {
name: 'subagent-fork',
inject: [
'subagents',
],
effects: [
'subagents.registerProvider()',
],
})
}
/**
* No runtime invariant: this package exposes no independent event sequence or mutable data relation
* beyond contracts enforced at its owning seam.
*/
const install: InvariantInstaller = () => {}
/**
* Register this package's invariant companion.
@@ -30,3 +27,4 @@ const install: InvariantInstaller = (ctx, fail) => {
*/
export const apply = (ctx: Context): Promise<() => void> =>
Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install))
/* jscpd:ignore-end */

View File

@@ -1,24 +1,24 @@
/** Package-owned runtime contracts for @deepseek-ai/dsh-subagent-inprocess. @module @deepseek-ai/dsh-subagent-inprocess/invariant */
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-subagent-inprocess`.
* @module @deepseek-ai/dsh-subagent-inprocess/invariant
*/
/* jscpd:ignore-start */
import type { Context } from 'cordis'
import { assertInvariant, type InvariantInstaller } from '@deepseek-ai/dsh-invariants'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-inprocess'
/** Cordis companion plugin name. */
export const name = 'subagent-inprocess-invariant'
/** Services required before the companion can register. */
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/** Assert that structured-output guidance names the tool it actually installs. */
const install: InvariantInstaller = async (_ctx, fail) => {
const { STRUCTURED_OUTPUT_INSTRUCTION, STRUCTURED_OUTPUT_TOOL } = await import('./structured-protocol.ts')
assertInvariant(fail, /^[a-z][a-z0-9_]*$/.test(STRUCTURED_OUTPUT_TOOL),
'the structured-output tool must retain a stable lowercase protocol name')
assertInvariant(fail, STRUCTURED_OUTPUT_INSTRUCTION.includes(STRUCTURED_OUTPUT_TOOL),
'the structured-output instruction must name the exact installed tool')
}
/**
* No runtime invariant: this package exposes no independent event sequence or mutable data relation
* beyond contracts enforced at its owning seam.
*/
const install: InvariantInstaller = () => {}
/**
* Register this package's invariant companion.

View File

@@ -1,27 +1,24 @@
/** Package-owned runtime contract checks for `@deepseek-ai/dsh-subagent-spawn`. @module @deepseek-ai/dsh-subagent-spawn/invariant */
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-subagent-spawn`.
* @module @deepseek-ai/dsh-subagent-spawn/invariant
*/
/* jscpd:ignore-start */
import type { Context } from 'cordis'
import { observePluginInvariant, type InvariantInstaller } from '@deepseek-ai/dsh-invariants'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-spawn'
/** Cordis companion plugin name. */
export const name = 'subagent-spawn-invariant'
/** Services required before the companion can register. */
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/** Install checks for this package's active plugin fibers. */
const install: InvariantInstaller = (ctx, fail) => {
observePluginInvariant(ctx, fail, {
name: 'subagent-spawn',
inject: [
'subagents',
],
effects: [
'subagents.registerProvider()',
],
})
}
/**
* No runtime invariant: this package exposes no independent event sequence or mutable data relation
* beyond contracts enforced at its owning seam.
*/
const install: InvariantInstaller = () => {}
/**
* Register this package's invariant companion.
@@ -30,3 +27,4 @@ const install: InvariantInstaller = (ctx, fail) => {
*/
export const apply = (ctx: Context): Promise<() => void> =>
Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install))
/* jscpd:ignore-end */

View File

@@ -1,37 +1,24 @@
/** Package-owned runtime contracts for @deepseek-ai/dsh-subagent-subprocess. @module @deepseek-ai/dsh-subagent-subprocess/invariant */
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-subagent-subprocess`.
* @module @deepseek-ai/dsh-subagent-subprocess/invariant
*/
/* jscpd:ignore-start */
import type { Context } from 'cordis'
import { assertInvariant, type InvariantInstaller } from '@deepseek-ai/dsh-invariants'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-subprocess'
const SENSITIVE_ENV_PATTERN = /KEY|SECRET|TOKEN/i
/** Cordis companion plugin name. */
export const name = 'subagent-subprocess-invariant'
/** Services required before the companion can register. */
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/** Assert ambient credential scrubbing and explicit credential precedence. */
const install: InvariantInstaller = async (_ctx, fail) => {
const { buildChildEnv } = await import('./index.ts')
const ambientProbe = `DSH_INVARIANT_AMBIENT_TOKEN_${process.pid}`
assertInvariant(fail, SENSITIVE_ENV_PATTERN.test(ambientProbe),
'the invariant ambient probe must remain credential-shaped')
process.env[ambientProbe] = 'must-not-reach-child'
let scrubbed: NodeJS.ProcessEnv
try {
scrubbed = buildChildEnv({})
} finally {
Reflect.deleteProperty(process.env, ambientProbe)
}
assertInvariant(fail, !Object.hasOwn(scrubbed, ambientProbe),
'subprocess environments must omit every credential-shaped ambient variable')
const explicit = buildChildEnv({ DSH_INVARIANT_TOKEN: 'explicit-child-value' })
assertInvariant(fail, explicit.DSH_INVARIANT_TOKEN === 'explicit-child-value',
'explicit child credentials must be applied after ambient scrubbing')
}
/**
* No runtime invariant: this package exposes no independent event sequence or mutable data relation
* beyond contracts enforced at its owning seam.
*/
const install: InvariantInstaller = () => {}
/**
* Register this package's invariant companion.

View File

@@ -1,30 +1,89 @@
/** Package-owned runtime contract checks for `@deepseek-ai/dsh-subagent`. @module @deepseek-ai/dsh-subagent/invariant */
/** Package-owned subagent registry and lifecycle invariants. @module @deepseek-ai/dsh-subagent/invariant */
import type { Context } from 'cordis'
import { observePluginInvariant, type InvariantInstaller } from '@deepseek-ai/dsh-invariants'
import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants'
import type { SubagentProvider } from './types.ts'
import type { SubagentRunEndInfo, SubagentRunInfo } from './index.ts'
const PACKAGE_NAME = '@deepseek-ai/dsh-subagent'
/** Cordis companion plugin name. */
export const name = 'subagent-invariant'
/** Services required before the companion can register. */
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/** Install checks for this package's active plugin fibers. */
const install: InvariantInstaller = (ctx, fail) => {
observePluginInvariant(ctx, fail, {
name: 'SubagentService',
effects: [
'ctx.provide("subagents")',
],
services: [
'subagents',
],
})
/** Assert that a terminal lifecycle payload matches its start identity. */
function validateRunEnd(start: SubagentRunInfo, end: SubagentRunEndInfo, fail: InvariantFailure): void {
if (start.provider !== end.provider || start.id !== end.id || start.local !== end.local) {
fail(`subagent/end identity diverges from subagent/start for run ${JSON.stringify(end.runId)}`)
}
}
/** Install provider-registry and start/end pairing checks. */
const install: InvariantInstaller = Object.assign((ctx: Context, fail: InvariantFailure) => {
const providers = new Set(ctx.subagents.list())
const runs = new Map<string, SubagentRunInfo>()
const stagedProviders = new WeakSet<SubagentProvider>()
const stagedRemovals = new Set<string>()
const stagedStarts = new WeakSet<SubagentRunInfo>()
const stagedEnds = new WeakSet<SubagentRunEndInfo>()
ctx.on('internal/dispatch', (_mode, eventName, args) => {
if (eventName === 'subagent/provider-added') {
const provider = args[0] as SubagentProvider
if (provider.name.length === 0) fail('subagent provider names must be non-empty')
if (providers.has(provider.name)) fail(`subagent/provider-added repeated ${JSON.stringify(provider.name)}`)
stagedProviders.add(provider)
return
}
if (eventName === 'subagent/provider-removed') {
const providerName = args[0] as string
if (!providers.has(providerName)) fail(`subagent/provider-removed names unknown provider ${JSON.stringify(providerName)}`)
stagedRemovals.add(providerName)
return
}
if (eventName === 'subagent/start') {
const info = args[0] as SubagentRunInfo
if (!providers.has(info.provider)) fail(`subagent/start names inactive provider ${JSON.stringify(info.provider)}`)
if (String(info.runId).length === 0 || String(info.id).length === 0) {
fail('subagent/start runId and child id must be non-empty')
}
if (runs.has(info.runId)) fail(`subagent/start repeated run id ${JSON.stringify(info.runId)}`)
stagedStarts.add(info)
return
}
if (eventName !== 'subagent/end') return
const info = args[0] as SubagentRunEndInfo
const start = runs.get(info.runId)
if (start === undefined) fail(`subagent/end has no matching subagent/start for run ${JSON.stringify(info.runId)}`)
validateRunEnd(start, info, fail)
stagedEnds.add(info)
}, { global: true })
ctx.on('subagent/provider-added', (provider) => {
/* v8 ignore next -- internal/dispatch stages the same provider object */
if (!stagedProviders.delete(provider)) return
providers.add(provider.name)
}, { global: true })
ctx.on('subagent/provider-removed', (providerName) => {
/* v8 ignore next -- internal/dispatch stages the same provider name */
if (!stagedRemovals.delete(providerName)) return
providers.delete(providerName)
}, { global: true })
ctx.on('subagent/start', (info) => {
/* v8 ignore next -- internal/dispatch stages the same lifecycle object */
if (!stagedStarts.delete(info)) return
runs.set(info.runId, info)
}, { global: true })
ctx.on('subagent/end', (info) => {
/* v8 ignore next -- internal/dispatch stages the same lifecycle object */
if (!stagedEnds.delete(info)) return
runs.delete(info.runId)
}, { global: true })
}, { inject: ['subagents'] })
/**
* Register this package's invariant companion.
* Register the subagent invariant companion.
* @param ctx - Cordis context carrying the invariant service.
* @returns the installed registration's disposer after setup succeeds.
*/

View File

@@ -0,0 +1,82 @@
import { describe, expect, it } from 'vitest'
import { Context } from 'cordis'
import { scopeTarget } from '@deepseek-ai/dsh-scope'
import { SessionId } from '@deepseek-ai/dsh-session'
import SubagentService, { SubagentRunId } from '@deepseek-ai/dsh-subagent'
import type {
SubagentProvider,
SubagentRunEndInfo,
SubagentRunInfo,
} from '@deepseek-ai/dsh-subagent'
import * as SubagentInvariant from '@deepseek-ai/dsh-subagent/invariant'
import InvariantService from '@deepseek-ai/dsh-invariants'
async function setup(): Promise<Context> {
const ctx = new Context()
await ctx.plugin(SubagentService)
await ctx.plugin(InvariantService)
await ctx.plugin(SubagentInvariant)
return ctx
}
const provider = (name: string): SubagentProvider => ({
name,
capabilities: { outputSchema: false, depthLimit: false, toolFilter: false, persona: false },
inheritsParentContext: false,
start: async () => { throw new Error('not used') },
})
const start = (overrides: Partial<SubagentRunInfo> = {}): SubagentRunInfo => ({
runId: SubagentRunId('run-1'),
provider: 'mock',
id: SessionId('child-1'),
local: false,
...overrides,
})
const end = (overrides: Partial<SubagentRunEndInfo> = {}): SubagentRunEndInfo => ({
...start(),
stopReason: 'completed',
...overrides,
})
function emitRun(ctx: Context, name: 'subagent/start', info: SubagentRunInfo): void
function emitRun(ctx: Context, name: 'subagent/end', info: SubagentRunEndInfo): void
function emitRun(ctx: Context, name: 'subagent/start' | 'subagent/end', info: SubagentRunInfo | SubagentRunEndInfo): void {
ctx.emit(scopeTarget(ctx.subagents, {}), name as 'subagent/start', info)
}
describe('subagent invariants', () => {
it('accepts provider and run lifecycle pairs', async () => {
const ctx = await setup()
const mock = provider('mock')
ctx.emit('subagent/provider-added', mock)
emitRun(ctx, 'subagent/start', start())
emitRun(ctx, 'subagent/end', end())
ctx.emit('subagent/provider-removed', 'mock')
ctx.emit('tools/change')
})
it('rejects malformed provider transitions', async () => {
const ctx = await setup()
expect(() => { ctx.emit('subagent/provider-added', provider('')) }).toThrow(/names must be non-empty/)
const mock = provider('mock')
ctx.emit('subagent/provider-added', mock)
expect(() => { ctx.emit('subagent/provider-added', mock) }).toThrow(/repeated "mock"/)
expect(() => { ctx.emit('subagent/provider-removed', 'missing') }).toThrow(/unknown provider/)
})
it('rejects malformed and unpaired run transitions', async () => {
const ctx = await setup()
expect(() => { emitRun(ctx, 'subagent/start', start()) }).toThrow(/inactive provider/)
ctx.emit('subagent/provider-added', provider('mock'))
expect(() => { emitRun(ctx, 'subagent/start', start({ runId: SubagentRunId('') })) })
.toThrow(/runId and child id must be non-empty/)
emitRun(ctx, 'subagent/start', start())
expect(() => { emitRun(ctx, 'subagent/start', start()) }).toThrow(/repeated run id/)
expect(() => { emitRun(ctx, 'subagent/end', end({ runId: SubagentRunId('missing') })) })
.toThrow(/no matching subagent\/start/)
expect(() => { emitRun(ctx, 'subagent/end', end({ id: SessionId('other') })) })
.toThrow(/identity diverges/)
})
})

View File

@@ -1,29 +1,24 @@
/** Package-owned runtime contract checks for `@deepseek-ai/dsh-tool-subagent`. @module @deepseek-ai/dsh-tool-subagent/invariant */
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-tool-subagent`.
* @module @deepseek-ai/dsh-tool-subagent/invariant
*/
/* jscpd:ignore-start */
import type { Context } from 'cordis'
import { observePluginInvariant, type InvariantInstaller } from '@deepseek-ai/dsh-invariants'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-tool-subagent'
/** Cordis companion plugin name. */
export const name = 'tool-subagent-invariant'
/** Services required before the companion can register. */
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/** Install checks for this package's active plugin fibers. */
const install: InvariantInstaller = (ctx, fail) => {
observePluginInvariant(ctx, fail, {
name: 'tool-subagent',
inject: [
'tools',
'subagents',
],
effects: [
'ctx.on("subagent/provider-added")',
'ctx.on("subagent/provider-removed")',
],
})
}
/**
* No runtime invariant: this model-facing adapter has no independent lifecycle stream; execution
* relations are owned by the capability seam it calls.
*/
const install: InvariantInstaller = () => {}
/**
* Register this package's invariant companion.
@@ -32,3 +27,4 @@ const install: InvariantInstaller = (ctx, fail) => {
*/
export const apply = (ctx: Context): Promise<() => void> =>
Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install))
/* jscpd:ignore-end */