Merge remote-tracking branch 'origin/master' into dshw/pr-deepseek-harness-deepseek-harness-2731

# Conflicts:
#	packages/util/brand/README.i18n.yaml
#	packages/util/brand/README.md
#	packages/util/brand/README.zh.md
This commit is contained in:
_Kerman
2026-08-26 10:35:38 +08:00
1275 changed files with 62320 additions and 14129 deletions
@@ -4,6 +4,7 @@ import { describe, expect, it } from 'vitest'
import {
checkExperimentalDependencyIsolation,
checkExperimentalManifest,
expectedDshPackageFiles,
type WorkspaceManifest,
} from './check-workspace-constraints.ts'
@@ -74,3 +75,17 @@ describe('experimental workspace constraints', () => {
])
})
})
describe('package payload constraints', () => {
it('includes a declared profile patch without a package-name allowlist', () => {
expect(expectedDshPackageFiles({
name: '@deepseek-ai/dsh-private-profile',
dsh: { bundle: { patch: './cordis.patch.yml' } },
})).toEqual([
'lib/index.js',
'lib/invariant.js',
'cordis.patch.yml',
'lib/types/**/*.d.ts',
])
})
})
+1 -1
View File
@@ -174,7 +174,7 @@ function sameStringList(actual: readonly string[] | undefined, expected: readonl
return !!actual && actual.length === expected.length && actual.every((value, index) => value === expected[index])
}
function expectedDshPackageFiles(manifest: PackageManifest): readonly string[] {
export function expectedDshPackageFiles(manifest: PackageManifest): readonly string[] {
const declaredPatch = manifest.dsh?.bundle?.patch
const bundleFiles = declaredPatch === undefined ? [] : [declaredPatch.replace(/^\.\//, '')]
const extras = [
+16
View File
@@ -39,4 +39,20 @@ export const coverageExemptHeavySuites: readonly CoverageExemptSuite[] = [
{ filter: 'scripts/oxlint-contract.spec.ts', exclude: 'scripts/oxlint-contract.spec.ts' },
{ filter: 'scripts/change-scope.spec.ts', exclude: 'scripts/change-scope.spec.ts' },
{ filter: 'scripts/translation-pairing-merge.spec.ts', exclude: 'scripts/translation-pairing-merge.spec.ts' },
// Spawns the full-corpus transform gate in a child process (Node's ESM
// loader is its oracle), so no measured file executes in-process; the
// package src is threshold-excluded in vitest.config.ts. A single
// 900s-budget case; running it inside an instrumented partition exceeds
// the Windows partition budget under load.
{
filter: 'packages/experimental/webworker-runtime/tests/compile/transform-corpus.spec.ts',
exclude: 'packages/experimental/webworker-runtime/tests/compile/transform-corpus.spec.ts',
},
// Built-artifact proof. Packer/runtime src is threshold-excluded, and the
// native Windows aggregate makes this uninstrumented gate wait for build so
// the suite never observes a partially emitted workspace closure.
{
filter: 'packages/experimental/webworker-packer/tests/image-loadable.spec.ts',
exclude: 'packages/experimental/webworker-packer/tests/image-loadable.spec.ts',
},
]
+265
View File
@@ -0,0 +1,265 @@
/**
* Quick comprehensive documentation-standard tests: the reference example
* stays valid, the consolidated `dsh-doc` skill carries no stale copied
* website values or prototype-era language, and the kind system maps each
* label to exactly one skill template. These run in `pnpm run test` and
* `pnpm run test:docs` to guard the standard between heavier corpus gates.
* @module scripts/doc-standard.spec
*/
import { existsSync, globSync, readFileSync } from 'node:fs'
import { resolve, sep } from 'node:path'
import { load } from 'js-yaml'
import { describe, expect, it } from 'vitest'
const root = resolve(import.meta.dirname, '..')
const PACKAGE_README_GLOBS = [
'packages/README.md',
'packages/README.zh.md',
'packages/*/README.md',
'packages/*/README.zh.md',
'packages/*/*/README.md',
'packages/*/*/README.zh.md',
] as const
function packageReadmes(): string[] {
return PACKAGE_README_GLOBS
.flatMap(pattern => globSync(pattern, { cwd: root, exclude: ['**/node_modules/**'] }))
.map(file => file.replaceAll('\\', '/'))
.sort()
}
/**
* The kind system: each label maps to exactly one template in the dsh-doc
* skill. The check derives the expected kind from the same mechanical facts
* the skill documents; a kind without a template, a template without a kind,
* or a document whose kind does not match its position fails here.
*/
const KIND_TEMPLATES: Readonly<Record<string, string>> = {
'package-group': '.agents/skills/dsh-doc/templates/package-group.md',
'package-reference': '.agents/skills/dsh-doc/templates/package-reference.md',
'package-library': '.agents/skills/dsh-doc/templates/package-library.md',
'package-bundle': '.agents/skills/dsh-doc/templates/package-bundle.md',
}
/**
* Audited packages whose entry is a plain module API rather than a Cordis
* plugin (`apply` export or a default service export) or an installable
* bundle (`dsh.bundle.patch`). Each entry names why the package is a
* library; the check re-derives the entry shape so a stale entry fails loud.
*/
const PACKAGE_LIBRARIES: Readonly<Record<string, string>> = {
'packages/boot/app-boot': 'Boot library the app bins import; plain helper exports.',
'packages/boot/cmdline': 'Command-line library the app bins import; plain module exports.',
'packages/client/store': 'Browser-side state primitives; plain function/type exports.',
'packages/client/ui-primitives': 'Browser-side UI component library; plain component exports.',
'packages/client/ui-slots': 'Browser-side slot-map declarations; plain type exports.',
'packages/client/web': 'Browser application boot library; exports the app entry and static module table.',
'packages/code-runtime/code-runtime-python': 'Host-side protocol library for the CPython subprocess runtime.',
'packages/core/scope': 'Scoped-context primitives; exports functions and types without a plugin entry.',
'packages/experimental/webworker-packer': 'Build-time VFS image packer and command library.',
'packages/experimental/webworker-runtime': 'Browser worker runtime library with explicit host entry points.',
'packages/hooks/hook-protocol': 'Shared wire-protocol library between the hook bridges.',
'packages/identity/anonymous-user-id': 'Harness-home identity helper with no plugin registration.',
'packages/sandbox/sandbox-windows-acl': 'Windows ACL sandbox library consumed by sandbox-local.',
'packages/sdk/client': 'Client-process library; the spawned runtime owns plugin behavior.',
'packages/sdk/protocol': 'Wire-protocol library with type declarations only.',
'packages/session/session-telemetry': 'Telemetry Service Definition and capture library; providers mount the backend.',
'packages/session/session-title-llm': 'Shared LLM title-provider registration and request policy.',
'packages/subagent/subagent-in-process-driver': 'Shared one-shot child-agent driver used by provider plugins.',
'packages/subprocess/win32-process': 'Low-level Win32 process and Job Object primitives.',
'packages/test-support/session-snapshot': 'Test infrastructure; mounts nothing into a product composition.',
'packages/test-support/agent-loop-testkit': 'Test helper library; mounts nothing into a product composition.',
'packages/test-support/client-runtime': 'Browser-side test infrastructure.',
'packages/test-support/llm-mock-server': 'Test server library; substitutes provider wire behavior.',
'packages/test-support/loader-smoke': 'Test harness library; mounts nothing into a product composition.',
'packages/typert/generator': 'Build-time generator run outside any agent runtime.',
'packages/typert/protocol': 'Compiler-independent protocol declarations.',
'packages/util/atomic-write': 'Zero-dependency filesystem write utility.',
'packages/util/brand': 'Type-only branding primitive erased at compile time.',
'packages/util/crypto': 'Zero-dependency identifier minting utility.',
'packages/util/home-paths': 'Zero-dependency harness-home path resolver.',
'packages/util/launch-environment': 'Zero-dependency environment resolver.',
'packages/util/native-command': 'Host-side subprocess runner utility.',
'packages/util/output-retention': 'Zero-dependency retention utility.',
'packages/util/timeout': 'Zero-dependency timeout utility.',
'packages/util/workspace-path': 'Zero-dependency Workspace path formatter.',
}
function readFrontmatter(file: string): Record<string, unknown> {
const source = readFileSync(resolve(root, file), 'utf8')
const match = /^---\n([\s\S]*?)\n---\n/u.exec(source)
expect(match, `${file}: YAML frontmatter`).not.toBeNull()
const metadata = load(match?.[1] ?? '')
expect(metadata, `${file}: frontmatter object`).toBeTypeOf('object')
expect(Array.isArray(metadata), `${file}: frontmatter object`).toBe(false)
return metadata as Record<string, unknown>
}
function packageDir(file: string): string {
return file.replaceAll('\\', '/').replace(/\/README\.zh\.md$/, '').replace(/\/README\.md$/, '')
}
/** Whether the package manifest declares `dsh.bundle.patch`. */
function declaresBundle(dir: string): boolean {
const manifest = resolve(root, dir, 'package.json')
if (!existsSync(manifest)) return false
const metadata = JSON.parse(readFileSync(manifest, 'utf8')) as { dsh?: { bundle?: { patch?: string } } }
return metadata.dsh?.bundle?.patch !== undefined
}
/** The expected kind for one package README, from the facts the skill documents. */
function expectedKind(file: string): string {
const normalized = file.replaceAll('\\', '/')
if (normalized.split('/').length <= 3) return 'package-group'
const dir = packageDir(normalized)
if (declaresBundle(dir)) return 'package-bundle'
if (Object.hasOwn(PACKAGE_LIBRARIES, dir)) return 'package-library'
return 'package-reference'
}
function packageReadmeMetadataErrors(file: string, metadata: Record<string, unknown>): string[] {
const errors: string[] = []
if (metadata.kind !== expectedKind(file)) errors.push(`kind must be ${expectedKind(file)}`)
if (typeof metadata.description !== 'string' || metadata.description.trim() === '') {
errors.push('description must be a non-empty string')
}
for (const field of ['name', 'audience', 'tags', 'i18n']) {
if (field in metadata) errors.push(`${field} is redundant or has no governed consumer`)
}
return errors
}
function packageReadmeStructureErrors(file: string, source: string): string[] {
const chinese = file.endsWith('.zh.md')
const required = chinese
? [[/^## 概述$/m, '概述'], [/^## 目录$/m, '目录'], [/^#{2,3} 开发备注$/m, '开发备注']] as const
: [[/^## Summary$/m, 'Summary'], [/^## Table of Contents$/m, 'Table of Contents'], [/^#{2,3} Dev Note$/m, 'Dev Note']] as const
return required.flatMap(([pattern, label]) => pattern.test(source) ? [] : [`missing ${label}`])
}
describe('dsh-doc skill consolidation', () => {
it('carries no prototype-era language', () => {
const files = [
'.agents/skills/dsh-doc/SKILL.md',
'.agents/skills/dsh-doc/references/metadata-links-i18n.md',
'.agents/skills/dsh-doc/references/structure-hierarchy.md',
'.agents/skills/dsh-doc/references/style.md',
'.agents/skills/dsh-doc/references/review.md',
'.agents/skills/dsh-doc/references/website-sync.md',
]
for (const file of files) {
const source = readFileSync(resolve(root, file), 'utf8')
expect(source, file).not.toMatch(/\bprototype\b/i)
}
})
it('copies no stale website sidebar or section-owner values', () => {
const source = readFileSync(resolve(root, '.agents/skills/dsh-doc/references/website-sync.md'), 'utf8')
expect(source).not.toContain('en-docs')
expect(source).not.toContain('sectionOrder')
})
it('keeps the reference example linked from the skill', () => {
const skill = readFileSync(resolve(root, '.agents/skills/dsh-doc/SKILL.md'), 'utf8')
expect(skill).toContain('session-persistence-sqlite/README.md')
expect(skill).toContain('session-persistence-sqlite/README.zh.md')
})
it('defines controlled English as a precision-preserving review discipline', () => {
const skill = readFileSync(resolve(root, '.agents/skills/dsh-doc/SKILL.md'), 'utf8')
const style = readFileSync(resolve(root, '.agents/skills/dsh-doc/references/style.md'), 'utf8')
expect(skill).toContain('references/style.md#controlled-technical-english')
expect(style).toContain('not certified ASD-STE100 compliance')
expect(style).toContain('review prompts, not mechanical gates')
expect(style).toContain('Never remove or strengthen `must`, `may`, `never`')
})
it('maps every kind label to exactly one skill template that exists', () => {
const templateFiles = globSync('.agents/skills/dsh-doc/templates/*.md', { cwd: root }).map(path => path.split(sep).join('/')).sort()
const registered = Object.values(KIND_TEMPLATES).sort()
expect(templateFiles).toEqual(registered)
for (const [kind, template] of Object.entries(KIND_TEMPLATES)) {
expect(existsSync(resolve(root, template)), `${kind}: template ${template}`).toBe(true)
}
})
it('maps package README kinds to their documentation standards', () => {
const files = packageReadmes()
expect(files.length).toBeGreaterThan(0)
for (const file of files) {
const metadata = readFrontmatter(file)
expect(packageReadmeMetadataErrors(file, metadata), file).toEqual([])
}
})
it('keeps the audited library registry accurate: every entry has a plain module entry and no bundle declaration', () => {
for (const [dir, reason] of Object.entries(PACKAGE_LIBRARIES)) {
expect(reason.trim().length, `${dir}: library justification`).toBeGreaterThan(0)
expect(declaresBundle(dir), `${dir}: a bundle declaration makes this package-bundle, not a library`).toBe(false)
const entry = resolve(root, dir, 'src/index.ts')
expect(existsSync(entry), `${dir}: library entry`).toBe(true)
const source = readFileSync(entry, 'utf8')
expect(source, `${dir}: entry must be a plain module, not a plugin`).not.toMatch(/export (?:default|\{[^}]*default[^}]*\} from)/u)
expect(source, `${dir}: entry must be a plain module, not a plugin`).not.toMatch(/export (?:async )?(?:function|const) apply\b/u)
}
})
it('keeps every package README on the summary, contents, and Dev Note skeleton', () => {
for (const file of packageReadmes().filter(file => file.split('/').length === 4)) {
const source = readFileSync(resolve(root, file), 'utf8')
expect(packageReadmeStructureErrors(file, source), file).toEqual([])
}
})
it('rejects redundant fields and a kind that does not match the README position', () => {
expect(packageReadmeMetadataErrors('packages/example/README.md', {
description: 'Example group.',
kind: 'package-reference',
name: 'example',
audience: ['developer'],
tags: ['example'],
i18n: { counterpart: 'README.zh.md' },
})).toEqual([
'kind must be package-group',
'name is redundant or has no governed consumer',
'audience is redundant or has no governed consumer',
'tags is redundant or has no governed consumer',
'i18n is redundant or has no governed consumer',
])
expect(packageReadmeMetadataErrors('packages\\example\\package\\README.md', {
description: 'Example package.',
kind: 'package-reference',
})).toEqual([])
})
it('rejects README-local i18n metadata', () => {
expect(packageReadmeMetadataErrors('packages\\example\\package\\README.md', {
description: 'Example package.',
kind: 'package-reference',
i18n: {
'counterpart': 'packages/example/package/README.zh.md',
'line-aligned': true,
},
})).toEqual([
'i18n is redundant or has no governed consumer',
])
})
})
describe('reference-example README pair', () => {
const dir = 'packages/session/session-persistence-sqlite'
it('keeps exact English/Chinese physical line alignment', () => {
const sourceLines = readFileSync(resolve(root, dir, 'README.md'), 'utf8').split('\n').length
const zhLines = readFileSync(resolve(root, dir, 'README.zh.md'), 'utf8').split('\n').length
expect(sourceLines).toBe(zhLines)
})
it('keeps the sidecar consistency record present', () => {
const sidecar = readFileSync(resolve(root, dir, 'README.i18n.yaml'), 'utf8')
expect(sidecar).toMatch(/^README\.md: [0-9a-f]{40}$/m)
expect(sidecar).toMatch(/^README\.zh\.md: [0-9a-f]{40}$/m)
})
})
+1 -1
View File
@@ -758,7 +758,7 @@ export const CORDIS_CATALOG_POLICY: CordisCatalogPolicy = {
{ name: 'ctx.effect', summary: 'Register a disposable side effect tied to the fiber.', source: 'vendor/cordis/src/fiber.ts:9' },
{ name: 'ctx.get / ctx.set / ctx.provide / ctx.accessor / ctx.mixin', summary: 'Low-level service-store access and binding.', source: 'vendor/cordis/src/reflect.ts:7' },
{ name: 'ctx.extend / ctx.isolate / ctx.intercept', summary: 'Derive a child context (scoped services / isolation / interception).', source: 'vendor/cordis/src/context.ts:42' },
{ name: 'ctx.root / ctx.scope / ctx.fiber / ctx.registry / ctx.reflect / ctx.events / ctx.logger', summary: 'Ambient handles onto the running context graph.', source: 'vendor/cordis/src/context.ts:16' },
{ name: 'ctx.root / ctx.fiber / ctx.registry / ctx.reflect / ctx.events / ctx.logger', summary: 'Ambient handles onto the running context graph.', source: 'vendor/cordis/src/context.ts:16' },
{ name: 'ctx.timer (+ interval / timeout / throttle / debounce)', summary: 'Disposable timer helpers. The `timer` key is provided at runtime; the four supported helpers are mixed onto ctx directly (declared via Pick).', source: 'vendor/timer/src/index.ts:4' },
{ name: 'ctx.loader', summary: 'The config Loader that booted the app (present under the loader).', source: 'vendor/loader/src/index.ts:30' },
{ name: 'ctx.hmr', summary: 'The hot-module-reload watcher (present under the hmr plugin).', source: 'vendor/hmr/src/index.ts:15' },
+1 -1
View File
@@ -14,7 +14,7 @@ const CLIENT_SERVICES: Readonly<Record<string, readonly string[]>> = {
locale: ['getLocale', 'getSnapshot', 'subscribe', 'setLocale', 'addLanguage', 'register', 'bind'],
sessions: ['open', 'openSubagent', 'setSubagentCatalogOpen', 'refreshSubagents', 'search', 'fork', 'scope', 'binding'],
slots: ['register', 'inject'],
theme: ['getTheme', 'setTheme', 'register', 'overrideTokens'],
theme: ['getTheme', 'setTheme', 'setFontSize', 'register', 'overrideTokens'],
uiWorkspace: [
'connectWorkspace', 'startSession', 'archiveSession', 'pickDirectory', 'listDirectory',
'createDirectory', 'openPath',
+23 -23
View File
@@ -104,7 +104,7 @@ const SERVICE_ROLES: ServiceRole[] = [
title: 'Durable binary attachment storage',
mode: 'seam',
implementations: ['attachment-local'],
consumers: ['host-runtime', 'llm-pi-ai'],
consumers: ['api-session-controller', 'host-apiproxy', 'tool-fs', 'llm-pi-ai', 'llm-deepseek'],
note: 'The host commits accepted images before session events; provider adapters resolve authorized durable references into provider-native content.',
},
{
@@ -146,7 +146,7 @@ const SERVICE_ROLES: ServiceRole[] = [
pkg: 'session',
title: 'In-memory session store',
mode: 'core',
consumers: ['agent-loop', 'agent', 'session-persistence', 'session-query', 'session-query-sqlite', 'subagent-inprocess', 'invariants', 'message-feedback'],
consumers: ['agent-loop', 'agent', 'session-persistence', 'session-query', 'session-query-sqlite', 'subagent-in-process-driver', 'invariants', 'message-feedback'],
note: 'Owns append-only Session instances and emits the durable session event feed.',
},
{
@@ -154,7 +154,7 @@ const SERVICE_ROLES: ServiceRole[] = [
pkg: 'api-session-controller',
title: 'Host Session Remote controller',
mode: 'core',
consumers: ['apiproxy'],
consumers: ['host-apiproxy'],
note: 'Owns Session commands, cold reads, durable-event following, live control state, and Agent activation policy; apiProxy reuses its inspection and Agent-resolution operations for Session-aware domains.',
},
{
@@ -202,7 +202,7 @@ const SERVICE_ROLES: ServiceRole[] = [
title: 'User-settings seam',
mode: 'seam',
implementations: ['settings-file'],
consumers: ['llm-deepseek', 'llm-pi-ai', 'apiproxy'],
consumers: ['llm-deepseek', 'llm-pi-ai', 'host-apiproxy'],
note: 'Plugins register namespace schemas and resolve layered values; providers store the raw document. The LLM adapters register their entry config as the composition base under the user section; the web gateway serves redacted layered descriptors and writes the user layer.',
},
{
@@ -219,7 +219,7 @@ const SERVICE_ROLES: ServiceRole[] = [
title: 'Credential seam',
mode: 'seam',
implementations: ['credentials-local'],
consumers: ['llm-deepseek', 'llm-pi-ai', 'apiproxy'],
consumers: ['llm-deepseek', 'llm-pi-ai', 'host-apiproxy'],
note: 'Configuration carries references to secrets; providers own the values. Consumers resolve per operation, so a rotated credential reaches the very next request; the web gateway exposes value-free views and write-only storage.',
},
{
@@ -269,7 +269,7 @@ const SERVICE_ROLES: ServiceRole[] = [
pkg: 'workspace',
title: 'Workspace entity registry',
mode: 'core',
consumers: ['apiproxy'],
consumers: ['api-workspace-controller', 'api-session-controller'],
note: 'Owns WorkspaceId-branded records over the domain facility; stable sessionIds accounts drive Host RPC and GUI projections.',
},
{
@@ -379,7 +379,7 @@ const SERVICE_ROLES: ServiceRole[] = [
pkg: 'agent',
title: 'Agent service',
mode: 'core',
consumers: ['agent-loop', 'acp', 'subagent-inprocess'],
consumers: ['agent-loop', 'acp', 'subagent-in-process-driver'],
note: 'Owns live Agent handles, the create/resume factory seam, and process-local initiator propagation.',
},
{
@@ -468,11 +468,11 @@ const SERVICE_ROLES: ServiceRole[] = [
},
{
key: 'approval',
pkg: 'approval',
pkg: 'user-approval',
title: 'Approval seam',
mode: 'seam',
implementations: ['acp'],
consumers: ['tools', 'tool-bash'],
implementations: [],
consumers: ['tools', 'tool-bash', 'acp'],
note: 'One-shot permission decisions dispatched over the `approval/request` waterfall; answerers are listeners (the ACP bridge for its own agents), absence fails closed to `unavailable`.',
},
{
@@ -488,7 +488,7 @@ const SERVICE_ROLES: ServiceRole[] = [
pkg: 'code-runtime',
title: 'Code-execution seam',
mode: 'seam',
implementations: ['code-runtime-worker'],
implementations: ['code-runtime-worker-thread'],
consumers: ['tools'],
note: 'Runs one model-written program against host-provided async bindings; backends differ by substrate and language (the tool registry consumes it for Code Mode).',
},
@@ -522,10 +522,10 @@ const SERVICE_ROLES: ServiceRole[] = [
},
{
key: 'agentTeams',
pkg: 'agent-team',
pkg: 'experimental-agent-team',
title: 'Agent Teams coordination domain',
mode: 'core',
consumers: ['tool-agent-team'],
consumers: ['experimental-tool-agent-team'],
note: 'Owns the implicit-root roster, durable peer mailbox, shared task DAG, and continuable-child lifecycle; tool-agent-team contributes the scoped model policy and controls.',
},
{
@@ -557,27 +557,27 @@ const SERVICE_ROLES: ServiceRole[] = [
},
{
key: 'directoryPicker',
pkg: 'directory-picker',
pkg: 'host-directory-picker',
title: 'Workspace-directory picking seam',
mode: 'seam',
implementations: ['directory-picker-native', 'directory-picker-browse'],
consumers: ['apiproxy'],
implementations: ['host-directory-picker-native', 'host-directory-picker-browse'],
consumers: ['host-apiproxy'],
note: 'Discriminated interaction capability: the native backend opens one OS chooser on the host display, the browse backend serves listing/creation primitives for the in-app browser; dual-face backends fill ui-workspace directory-flow slots from their browser halves (no wire advertisement).',
},
{
key: 'webServer',
pkg: 'webserver',
pkg: 'host-webserver',
title: 'HTTP route registration',
mode: 'core',
consumers: ['connection', 'modules', 'hmr'],
consumers: ['client-connection', 'client-modules', 'client-hmr'],
note: 'Plain node:http carrier: named-route registry, index transform taps, and the static dist fallback; web-transport plugins register their own routes.',
},
{
key: 'clientModules',
pkg: 'modules',
pkg: 'client-modules',
title: 'Client plugin graph host',
mode: 'core',
consumers: ['hmr'],
consumers: ['client-hmr'],
note: 'Composes the __DSH_BOOT__ entry graph from an incremental dsh.client scan, serves plugin bundles, and notifies rebuilt/graph-changed subscribers.',
},
{
@@ -602,16 +602,16 @@ const SERVICE_ROLES: ServiceRole[] = [
pkg: 'lsp',
title: 'Language-server navigation seam',
mode: 'seam',
implementations: ['lsp-local'],
implementations: ['lsp-stdio'],
consumers: ['tool-lsp'],
note: 'Provider registration and selection plus normalized query execution over exactly four operations; the seam offers no protocol escape hatch, so a backend translates into the normalized request and result.',
},
{
key: 'apiProxy',
pkg: 'apiproxy',
pkg: 'host-apiproxy',
title: 'Host API dispatch',
mode: 'core',
consumers: ['connection'],
consumers: ['client-connection'],
note: 'The transport-agnostic host gateway face: it dispatches browser API calls, and each open host stream subscribes to the events it forwards rather than being pushed to through a broadcast verb.',
},
{
+5 -6
View File
@@ -368,7 +368,7 @@ export function render(events: AnnotatedLogEventEntry[], envelopeTypes: EventEnv
'',
'This file is GENERATED from source (`scripts/gen-persistence-catalog.ts`) and verified fresh by `pnpm run verify-persistence-catalog` (part of `doc-sync`) — do not edit it by hand. Declaration blocks retain the source declaration and nested property JSDoc, removing only the indentation imposed by a containing interface/module, and use a `ts persistence-catalog` fence (skipped by doc-typecheck because declarations reference types from their owning modules). Type names in a payload link to the page that documents them. See [the persistence-log-catalog Agent Note](../.agents/notes/archived/process/2026-07-04-persistence-log-catalog.md).',
'',
'The envelope declarations below compose each event\'s `type`, monotonic `seq`, epoch-ms `time`, `data`, the optional `ignorable` unknown-type skip marker, and the conditional `surfaceOp`/`sourceEventSeqs` fields. **surface** marks a `SurfaceEventType` member: it produces an LLM message and declares how it joins the surface list. **log-only** marks everything else: a durable, replayable record with no derived-history contribution. Every payload is JSON-serializable (enforced at `Session.append`), and the whole format is pinned at `SESSION_FORMAT_VERSION = 0` — pre-release, no compatibility implied ([the version stance](subsystems/persistence.md)). Scope: the packages in this repo; a downstream plugin can merge further event types, which are outside this catalog by construction.',
'The envelope declarations below compose each event\'s `type`, monotonic `seq`, epoch-ms `time`, `data`, and the conditional `surfaceOp`/`sourceEventSeqs` fields. **surface** marks a `SurfaceEventType` member: it produces an LLM message and declares how it joins the surface list. **log-only** marks everything else: a durable, replayable record with no derived-history contribution. Every payload is JSON-serializable (enforced at `Session.append`), and the whole format is pinned at `SESSION_FORMAT_VERSION = 0` — pre-release, no compatibility implied ([the version stance](subsystems/persistence.md)). Scope: the packages in this repo; a downstream plugin can merge further event types, which are outside this catalog by construction.',
'',
'## Event envelope',
'',
@@ -394,7 +394,7 @@ export function render(events: AnnotatedLogEventEntry[], envelopeTypes: EventEnv
/**
* Render the runtime known-vocabulary module: every event type the packages in
* this repo can write, as a generated `ReadonlySet` the read path checks
* unknown-type refusal against (`SessionEvent.ignorable` contract).
* before reconstructing a stored session.
*/
export function renderKnownEventTypes(events: AnnotatedLogEventEntry[]): string {
const names = [...new Set(events.map(e => e.name))].sort()
@@ -409,10 +409,9 @@ export function renderKnownEventTypes(events: AnnotatedLogEventEntry[]): string
'/**',
' * Every `SessionEventMap` member declared in this repository — the event',
' * vocabulary this build understands. The persistence read path refuses to',
' * interpret a log containing a type outside this set unless the event',
' * carries the envelope\'s `ignorable` marker (see `SessionEvent.ignorable`',
' * in `./types.ts`): such a log was likely written by a newer harness, and',
' * silently skipping a required event would reconstruct a wrong session.',
' * interpret a log containing a type outside this set: such a log was likely',
' * written by a newer harness, and silently skipping the event could',
' * reconstruct a wrong session.',
' * Downstream (out-of-repo) plugin events are outside this list by',
' * construction; a registration surface for them is deferred until such a',
' * consumer exists.',
+13
View File
@@ -71,6 +71,7 @@ describe('gate graph validation', () => {
'check-all',
'hygiene',
'doc-sync',
'doc-quick',
] as const)('constructs and executes preflight for a valid non-empty %s graph', async (mode) => {
const subject = withPnpmEntrypoint(() => gatesForMode(mode))
const execute = vi.fn(async (item: Gate) => resultFor(item))
@@ -90,6 +91,13 @@ describe('gate graph validation', () => {
expect(ids).toContain('subsystem-pages')
})
it('derives the quick documentation aggregate from marked doc-sync leaves', () => {
const full = withPnpmEntrypoint(() => gatesForMode('doc-sync'))
const quick = withPnpmEntrypoint(() => gatesForMode('doc-quick'))
expect(quick).toEqual(full.filter(gate => gate.quick === true))
})
it('keeps the hygiene aggregate aligned with the package script checks', () => {
const ids = withPnpmEntrypoint(() => gatesForMode('hygiene').map(subject => subject.id))
@@ -167,9 +175,13 @@ describe('gate graph validation', () => {
const byId = new Map(complete.map(subject => [subject.id, subject]))
expect(byId.get('coverage')?.allowFailure).not.toBe(true)
expect(byId.get('coverage')?.needs).toContain('build')
expect(byId.get('coverage-exempt-heavy')?.allowFailure).not.toBe(true)
expect(byId.get('coverage')?.needs).toContain('build')
expect(byId.get('coverage-exempt-heavy')?.needs).toContain('build')
expect(byId.get('coverage-exempt-heavy')?.args).toContain(
'packages/experimental/webworker-packer/tests/image-loadable.spec.ts',
)
expect(observational).not.toHaveLength(0)
for (const gate of observational) {
const completeGate = byId.get(gate.id)
@@ -218,6 +230,7 @@ describe('gate graph validation', () => {
expect(coverage).toMatchObject({
displayCommand: 'DSH_COVERAGE_PARTITIONS=3 pnpm run test:coverage:partitioned',
args: ['/private/pnpm.cjs', 'run', 'test:coverage:partitioned'],
env: { DSH_COVERAGE_EXEMPT_HEAVY: '1' },
streamOutput: true,
})
})
+38 -16
View File
@@ -36,6 +36,7 @@ export type Mode =
| 'check-all'
| 'hygiene'
| 'doc-sync'
| 'doc-quick'
type GateResultStatus = 'passed' | 'failed' | 'skipped'
type GateState = 'pending' | 'running' | GateResultStatus
@@ -51,6 +52,8 @@ export interface Gate {
/** Gate ids that must settle, regardless of outcome, before this gate starts. */
after?: string[]
env?: Record<string, string | undefined>
/** Include this leaf in the build-free documentation aggregate. */
quick?: boolean
/** Keep a failure visible without failing the aggregate. */
allowFailure?: boolean
/** Write child output as it arrives instead of buffering it until completion. */
@@ -127,10 +130,11 @@ function parseMode(raw: string | undefined): Mode {
case 'check-all':
case 'hygiene':
case 'doc-sync':
case 'doc-quick':
return raw
default:
throw new Error(
`run-gates: expected mode ci-primary | ci-linux-primary | ci-static | ci-lint-contracts-ready | ci-coverage | ci-snapshot | ci-artifacts | ci-consumers | ci-windows-blocking | ci-windows-complete | ci-windows-observational | node-compat | check-all | hygiene | doc-sync, got ${JSON.stringify(raw)}.`,
`run-gates: expected mode ci-primary | ci-linux-primary | ci-static | ci-lint-contracts-ready | ci-coverage | ci-snapshot | ci-artifacts | ci-consumers | ci-windows-blocking | ci-windows-complete | ci-windows-observational | node-compat | check-all | hygiene | doc-sync | doc-quick, got ${JSON.stringify(raw)}.`,
)
}
}
@@ -150,7 +154,10 @@ export function defaultConcurrency(
if (selectedMode === 'ci-consumers') return { workers: total, source: 'ci-consumers gate count' }
// Local modes cap workers: several doc gates each build a full ts.Program,
// so an uncapped default on a large host trades wall clock for memory blowups.
const localCap = selectedMode === 'check-all' || selectedMode === 'hygiene' || selectedMode === 'doc-sync'
const localCap = selectedMode === 'check-all'
|| selectedMode === 'hygiene'
|| selectedMode === 'doc-sync'
|| selectedMode === 'doc-quick'
const modeLimit = localCap ? Math.min(4, available) : available
return {
workers: Math.min(total, modeLimit),
@@ -261,6 +268,8 @@ export function gatesForMode(selected: Mode): Gate[] {
]
case 'doc-sync':
return docSyncLeafGates()
case 'doc-quick':
return docQuickLeafGates()
}
}
@@ -683,38 +692,51 @@ function docSyncLeafGates(options: {
: [pnpmScript('doc-typecheck', options.docTypecheckScript ?? 'doc-typecheck', docTypecheckOptions)],
pnpmScript('docs-site-build', options.docsBuildScript ?? 'docs:build', { label: 'documentation build' }),
pnpmScript('doc-graphs', 'verify-doc-graphs', { label: 'doc graphs' }),
pnpmScript('markdown-links', 'verify-md-links', { label: 'markdown links' }),
pnpmScript('type-equivalence', 'verify-type-equiv', { label: 'type equivalence' }),
pnpmScript('markdown-links', 'verify-md-links', { label: 'markdown links', quick: true }),
pnpmScript('type-equivalence', 'verify-type-equiv', { label: 'type equivalence', quick: true }),
pnpmScript('cordis-catalog', 'verify-cordis-catalog', { label: 'cordis catalog' }),
pnpmScript('cordis-inspect-catalog', 'verify-cordis-inspect-catalog', { label: 'Cordis inspect catalog' }),
pnpmScript('mermaid', 'verify-mermaid'),
pnpmScript('scoped-events', 'verify-scoped-events', { label: 'scoped events' }),
pnpmScript('translation-pairing', 'verify-translation-pairing', { label: 'translation pairing' }),
pnpmScript('markdown-wrap', 'verify-md-wrap', { label: 'markdown wrap' }),
pnpmScript('translation-pairing', 'verify-translation-pairing', { label: 'translation pairing', quick: true }),
pnpmScript('markdown-wrap', 'verify-md-wrap', { label: 'markdown wrap', quick: true }),
pnpmScript('client-catalog', 'verify-client-catalog', { label: 'client catalog' }),
pnpmScript('export-jsdoc', 'verify-export-jsdoc', { label: 'export jsdoc' }),
pnpmScript('tool-catalog', 'verify-tool-catalog', { label: 'tool catalog' }),
pnpmScript('config-catalog', 'verify-config-catalog', { label: 'config catalog' }),
pnpmScript('persistence-catalog', 'verify-persistence-catalog', { label: 'persistence catalog' }),
pnpmScript('public-repository-links', 'verify-public-repository-links', { label: 'public repository links' }),
pnpmScript('doc-refs', 'verify-doc-refs', { label: 'doc refs' }),
pnpmScript('public-repository-links', 'verify-public-repository-links', { label: 'public repository links', quick: true }),
pnpmScript('doc-refs', 'verify-doc-refs', { label: 'doc refs', quick: true }),
pnpmScript('subsystem-pages', 'verify-subsystem-pages', { label: 'subsystem pages' }),
pnpmScript('package-paths', 'verify-package-paths', { label: 'package paths' }),
pnpmScript('config-source-ownership', 'verify-config-source-ownership', { label: 'config source ownership' }),
pnpmScript('package-readme-model-experience', 'verify-package-readme-model-experience', { label: 'package README model experience' }),
pnpmScript('agent-note-classification', 'verify-agent-note-classification', { label: 'agent note classification' }),
pnpmScript('agent-note-format', 'verify-agent-note-format', { label: 'agent note format' }),
pnpmScript('archived-agent-notes', 'verify-archived-agent-notes', { label: 'archived agent notes' }),
pnpmScript('skill-invocation-metadata', 'verify-skill-invocation-metadata', { label: 'skill invocation metadata' }),
pnpmScript('translation-prompt', 'verify-translation-prompt', { label: 'translation prompt' }),
pnpmScript('doc-budgets', 'verify-doc-budgets', { label: 'doc budgets' }),
pnpmScript('package-readme-model-experience', 'verify-package-readme-model-experience', { label: 'package README model experience', quick: true }),
pnpmScript('agent-note-classification', 'verify-agent-note-classification', { label: 'agent note classification', quick: true }),
pnpmScript('agent-note-format', 'verify-agent-note-format', { label: 'agent note format', quick: true }),
pnpmScript('archived-agent-notes', 'verify-archived-agent-notes', { label: 'archived agent notes', quick: true }),
pnpmScript('skill-invocation-metadata', 'verify-skill-invocation-metadata', { label: 'skill invocation metadata', quick: true }),
pnpmScript('translation-prompt', 'verify-translation-prompt', { label: 'translation prompt', quick: true }),
pnpmScript('doc-budgets', 'verify-doc-budgets', { label: 'doc budgets', quick: true }),
pnpmExec('doc-standard-tests', ['vitest', 'run', 'scripts/doc-standard.spec.ts'], {
label: 'documentation standard tests',
quick: true,
}),
pnpmExec('docs-site-projection', ['vitest', 'run', 'scripts/project-doc-site.spec.ts', 'scripts/verify-doc-site-fragments.spec.ts'], {
label: 'documentation site checks',
}),
pnpmScript('package-readme-limitations', 'verify-package-readme-limitations', { label: 'package README limitations' }),
pnpmScript('package-readme-limitations', 'verify-package-readme-limitations', { label: 'package README limitations', quick: true }),
]
}
/**
* The quick comprehensive documentation-standard aggregate for `test:docs`.
* It covers the prose, pairing, README, budget, and Agent Note gates
* without builds, generator regeneration, or the VitePress site build.
*/
function docQuickLeafGates(): Gate[] {
return docSyncLeafGates({ includeDocTypecheck: false }).filter(gate => gate.quick === true)
}
function builtBinSmokeGate(needs: string[] = ['build']): Gate {
return pnpmExec('built-bin-smoke', [
'vitest',
+25 -1
View File
@@ -40,7 +40,7 @@ function signature(markdown: string) {
'counterpart.zh.md',
{
repoRoot: process.cwd(), sourcePath: 'counterpart.md',
isTranslationPairSource: fixturePairSource, markdown,
isTranslationPairSource: fixturePairSource, repositoryFileExists: () => true, markdown,
},
)
}
@@ -250,6 +250,30 @@ describe('translation pairing switchers', () => {
})
})
describe('translation pairing link language parity', () => {
it('compares a .zh.md target and its .md sibling as the same document', () => {
const en = 'See [docs](persistence.md) and [notes](note.md#anchor).'
const zh = '参见[文档](persistence.zh.md)与[笔记](note.zh.md#anchor)。'
expect(
translationStructureDiff(
signature(en),
signature(zh),
),
).toEqual([])
})
it('still rejects a genuinely different target', () => {
const en = 'See [docs](persistence.md).'
const zh = '参见[文档](other.md)。'
expect(
translationStructureDiff(
signature(en),
signature(zh),
),
).not.toEqual([])
})
})
describe('translation pairing records', () => {
const paths = translationPairPaths('docs/foo.md')
const record = {
-6
View File
@@ -16,16 +16,10 @@ const root = resolve(import.meta.dirname, '..')
*/
export const GROUPS_WITHOUT_SUBSYSTEM_PAGE: Readonly<Record<string, string>> = {
acp: 'Protocol transport entry point; the server package README owns its interoperability contract.',
api: 'Remote transport and BFF assembly; Typert and the package READMEs own the underlying contracts.',
boot: 'Shared application-bin boot library rather than a runtime subsystem.',
bundle: 'Composition patch carriers whose mounted packages own all runtime contracts.',
e2b: 'Provider implementations of the filesystem and subprocess subsystems, not a new capability contract.',
examples: 'Non-product demonstration compositions whose mounted packages own all runtime contracts.',
experimental: 'Empty staging group; promoted packages move to their product-role group before release.',
feedback: 'One command producer and inline log-event payload; its package README and persistence catalog own the complete contract.',
hooks: 'External hook-protocol bridges over existing interception points, not a new Harness service.',
identity: 'Shared anonymous correlation values rather than authenticated account or authorization behavior.',
mcp: 'Integration adapter that contributes external tools through the existing tool registry.',
sdk: 'Out-of-process protocol and client packages whose package READMEs own the SDK contracts.',
util: 'Low-level primitives whose business semantics remain with their consuming subsystems.',
}