mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-11 04:00:38 +00:00
Merge codex/subprocess-win32-process-primitives into codex/subprocess-native-containment
This commit is contained in:
@@ -417,24 +417,63 @@ describe('Python release workflows', () => {
|
||||
})
|
||||
|
||||
describe('Issue lifecycle workflow', () => {
|
||||
it('uses explicit review handoff events without rerunning when a draft becomes ready', () => {
|
||||
it('runs the lifecycle job on every PR/review event but gates token and board steps', () => {
|
||||
const lifecycle = loadWorkflow('.github/workflows/issue-lifecycle.yml')
|
||||
const policy = loadWorkflow('.github/workflows/issue-policy.yml')
|
||||
const lifecycleJob = workflowJob(lifecycle, 'lifecycle')
|
||||
if (!Array.isArray(lifecycleJob.steps)) throw new TypeError('Issue lifecycle job must define steps')
|
||||
|
||||
// The job has no job-level `if`, so it is listed on every pull_request /
|
||||
// pull_request_review event and reports success instead of a gray skip. The
|
||||
// write-capable steps are gated at step level so approved/commented reviews
|
||||
// never mint a Project/Issue App token nor touch the board.
|
||||
expect(lifecycle.on).toHaveProperty('pull_request')
|
||||
expect(lifecycle.on).toHaveProperty('pull_request_review')
|
||||
expect(lifecycleJob.if).toBeUndefined()
|
||||
// Keep the subscription-type gates: issue-lifecycle does not re-subscribe
|
||||
// ready_for_review (issue-policy owns that) and only reacts to submitted
|
||||
// review events.
|
||||
const lifecyclePullRequest = workflowEvent(lifecycle, 'pull_request')
|
||||
const lifecycleReview = workflowEvent(lifecycle, 'pull_request_review')
|
||||
const lifecycleJob = workflowJob(lifecycle, 'lifecycle')
|
||||
const policy = loadWorkflow('.github/workflows/issue-policy.yml')
|
||||
const policyPullRequest = workflowEvent(policy, 'pull_request')
|
||||
|
||||
expect(lifecyclePullRequest.types).not.toContain('ready_for_review')
|
||||
expect(lifecyclePullRequest.types).toContain('review_requested')
|
||||
expect(lifecycleReview.types).toEqual(['submitted'])
|
||||
expect(lifecycleJob.if).toBe(
|
||||
"${{ github.event_name != 'pull_request_review' || (github.event.action == 'submitted' && github.event.review.state == 'changes_requested') }}",
|
||||
)
|
||||
const gated = "${{ github.event_name != 'pull_request_review' || github.event.review.state == 'changes_requested' }}"
|
||||
const steps = lifecycleJob.steps.filter(isRecord)
|
||||
const tokenStep = steps.find(s => s.name === 'Create project token')
|
||||
const handleStep = steps.find(s => s.name === 'Handle repository event')
|
||||
expect(tokenStep).toMatchObject({ if: gated })
|
||||
expect(handleStep).toMatchObject({ if: gated })
|
||||
|
||||
// issue-policy owns PR validation; it is read-only and a real gate.
|
||||
const policyPullRequest = workflowEvent(policy, 'pull_request')
|
||||
expect(policyPullRequest.types).toContain('ready_for_review')
|
||||
})
|
||||
})
|
||||
|
||||
describe('npm release workflows', () => {
|
||||
it('keeps publication dispatch-only and pack in the PR workflow', () => {
|
||||
// pack stays in the PR/master release workflows so a PR proves the set packs.
|
||||
for (const file of ['release.yml', 'release-vendor.yml']) {
|
||||
const workflow = loadWorkflow(`.github/workflows/${file}`)
|
||||
if (!isRecord(workflow.jobs)) throw new TypeError(`${file} must define jobs`)
|
||||
expect(Object.keys(workflow.jobs).sort()).toEqual(['pack'])
|
||||
}
|
||||
|
||||
// publication is workflow_dispatch-only (never a PR check) and keeps the
|
||||
// npm-publish environment plus the shared dist-tag group.
|
||||
for (const file of ['release-publish.yml', 'release-vendor-publish.yml']) {
|
||||
const workflow = loadWorkflow(`.github/workflows/${file}`)
|
||||
if (!isRecord(workflow.on) || !isRecord(workflow.jobs)) throw new TypeError(`${file} must define on and jobs`)
|
||||
expect(Object.keys(workflow.on)).toEqual(['workflow_dispatch'])
|
||||
const publish = workflow.jobs.publish
|
||||
if (!isRecord(publish)) throw new TypeError(`${file} must define a publish job`)
|
||||
expect(publish.environment).toBe('npm-publish')
|
||||
expect(publish.concurrency).toMatchObject({ group: 'Release-publish' })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('Git hooks', () => {
|
||||
it('leaves frozen Agent Note sidecars to the archive verifier', () => {
|
||||
const lefthook = loadWorkflow('lefthook.yml')
|
||||
|
||||
@@ -26,6 +26,7 @@ const dshBuildWorkflows = [
|
||||
'e2b-e2e.yml',
|
||||
'e2e.yml',
|
||||
'release.yml',
|
||||
'release-publish.yml',
|
||||
'sandbox.yml',
|
||||
]
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ export const SERVICE_PAGE: Record<string, string> = {
|
||||
commands: 'commands.md',
|
||||
compaction: 'compaction.md',
|
||||
cordisInspect: 'extensions.md',
|
||||
authorization: 'credentials.md',
|
||||
credentials: 'credentials.md',
|
||||
directoryPicker: 'workspace.md',
|
||||
dynamicCordisRunner: 'extensions.md',
|
||||
@@ -172,6 +173,7 @@ export const EVENT_SCOPE_PAGE: Record<string, string> = {
|
||||
'approval': 'approval.md',
|
||||
'commands': 'commands.md',
|
||||
'cordis': 'extensions.md',
|
||||
'authorization': 'credentials.md',
|
||||
'credentials': 'credentials.md',
|
||||
'domain': 'storage.md',
|
||||
'fs': 'filesystem.md',
|
||||
@@ -184,6 +186,7 @@ export const EVENT_SCOPE_PAGE: Record<string, string> = {
|
||||
'system-prompt': 'system-prompt.md',
|
||||
'session-telemetry': 'session-telemetry.md',
|
||||
'tools': 'tools.md',
|
||||
'webserver': 'web-server.md',
|
||||
'workflow': 'workflow.md',
|
||||
}
|
||||
|
||||
@@ -463,8 +466,23 @@ export const LINK_MAP: Readonly<Record<string, string>> = {
|
||||
SettingsPathOp: 'settings.md',
|
||||
SettingsDescribeOptions: 'settings.md',
|
||||
SettingsUpdateSource: 'settings.md',
|
||||
AuthorizationEntry: 'credentials.md',
|
||||
AuthorizationFlow: 'credentials.md',
|
||||
AuthorizationInteraction: 'credentials.md',
|
||||
AuthorizationMethod: 'credentials.md',
|
||||
AuthorizationNotice: 'credentials.md',
|
||||
AuthorizationOutcome: 'credentials.md',
|
||||
AuthorizationPrompt: 'credentials.md',
|
||||
AuthorizationRequest: 'credentials.md',
|
||||
AuthorizationSession: 'credentials.md',
|
||||
AuthorizationSettlement: 'credentials.md',
|
||||
AuthorizationStatus: 'credentials.md',
|
||||
CredentialRef: 'credentials.md',
|
||||
CredentialKey: 'credentials.md',
|
||||
CredentialInfo: 'credentials.md',
|
||||
CredentialRecord: 'credentials.md',
|
||||
CredentialRecordEntry: 'credentials.md',
|
||||
CredentialRecordInfo: 'credentials.md',
|
||||
ResolvedCredential: 'credentials.md',
|
||||
AskUserQuestionAnswer: 'user-questions.md',
|
||||
AskUserQuestionRequest: 'user-questions.md',
|
||||
@@ -480,6 +498,7 @@ export const LINK_MAP: Readonly<Record<string, string>> = {
|
||||
PresetSpec: 'permission-presets.md',
|
||||
InvariantInstaller: 'invariants.md',
|
||||
WebRoute: 'web-server.md',
|
||||
IndexInjection: 'web-server.md',
|
||||
StorageBackend: 'storage.md',
|
||||
StorageForms: 'storage.md',
|
||||
Domain: 'storage.md',
|
||||
|
||||
@@ -189,6 +189,15 @@ const SERVICE_ROLES: ServiceRole[] = [
|
||||
consumers: ['llm-deepseek', 'llm-pi-ai', '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.',
|
||||
},
|
||||
{
|
||||
key: 'authorization',
|
||||
pkg: 'authorization',
|
||||
title: 'Authorization flow registry',
|
||||
mode: 'seam',
|
||||
implementations: [],
|
||||
consumers: ['llm-pi-ai'],
|
||||
note: 'Flows are registered by the plugin that knows how to obtain one credential and keyed by the record they write; the seam owns the conversation and the one-attempt-per-key lifecycle, never the protocol.',
|
||||
},
|
||||
{
|
||||
key: 'sessionTelemetry',
|
||||
pkg: 'session-telemetry',
|
||||
|
||||
@@ -133,6 +133,7 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly<Record<string, SentenceContract>> = {
|
||||
'packages/settings/settings-file': { kind: 'indirect', reason: 'The file provider stores and publishes namespace sections; consumers of ctx.settings own any model-facing behavior.' },
|
||||
'packages/credentials/credentials': { kind: 'indirect', reason: 'The seam resolves credential references; the consuming adapter owns every model-facing use a value authorizes.' },
|
||||
'packages/credentials/credentials-local': { kind: 'indirect', reason: 'The file/environment provider stores credential values; consumers of ctx.credentials own any model-facing behavior.' },
|
||||
'packages/credentials/authorization': { kind: 'none', reason: 'A configuration-time conversation with a human; no flow, notice, or prompt reaches a model request.' },
|
||||
'packages/util/atomic-write': { kind: 'none', reason: 'Pure filesystem write primitive; registers nothing model-facing.' },
|
||||
'packages/session/session-telemetry': { kind: 'none', reason: 'The seam observes the session stream and hands redacted copies outward; it registers nothing model-facing.' },
|
||||
'packages/session/session-telemetry-otel': { kind: 'none', reason: 'The backend forwards seam records into the OTel SDK pipeline and registers nothing model-facing.' },
|
||||
|
||||
Reference in New Issue
Block a user