subprocess: one explicit env channel on the spawn spec
Drop SubprocessSpawnSpec.dshEnv and splitEnvChannels(); childEnv() is now scrubbed-base + explicit entries with no namespace validation. The invariant dropped is the reserved-namespace check on explicit entries (DSH_* rejected from env, non-DSH_* rejected from dshEnv). Explicit-entry trust already covers it: an explicit credential-shaped entry has always merged after the scrub as a deliberate caller opt-in, and an explicit DSH_* entry is the same deliberate act — the staleness invariant lives entirely in scrubbedParentEnv dropping AMBIENT credential-shaped and DSH_* names, which stays. The validation's only observed effect was rejecting legitimate explicit entries: both recent CI breakages (DSH_GATE_CONCURRENCY exported into every job crashing lsp specs, DSH_PERMISSION_MODE in acp config.env crashing the child spawn) were this check firing on values a caller meant to pass, each fixed by routing around the bureaucracy the seam itself imposed. The bash seam keeps its own request/spec dshEnv field: that is bash-owned trusted-plugin vocabulary (the ctx.bashEnv collected overlay) whose merge-last position guarantees a caller env entry cannot displace a managed fact; bash-local now flattens ENV_OVERRIDES -> spec.env -> spec.dshEnv into the seam's one env map. subagent-acp and lsp-local pass their single config env map straight through. DshEnvironment/DshEnvironmentKey/DSH_ENV_PREFIX stay on the subprocess seam as the namespace vocabulary (bash re-exports them; scrubbedParentEnv filters on the prefix). Tests: the two channel-rejection specs and the splitEnvChannels partition spec are deleted; one spawn spec now proves an explicit DSH_* env entry reaches the child while an ambient one is scrubbed; the acp/lsp forwarding specs keep their MOCK_ECHO_ENV / LSP_FAKE_ECHO_ENV assertions with the split comments rewritten to merge-after-scrub. Docs (en+zh, re-recorded) and the owning Agent Notes updated; cordis api/services catalogs regenerated.
This commit is contained in:
@@ -51,10 +51,10 @@ describe('LspConnection', () => {
|
||||
expect(conn.pid).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('routes explicit DSH_* env entries onto the managed channel', async () => {
|
||||
// A configured DSH_* fact must reach the child: the ordinary channel
|
||||
// rejects the reserved namespace, so the connection's spawn must split it
|
||||
// onto dshEnv. The fixture echoes the named variable back as hover text.
|
||||
it('forwards explicit DSH_* env entries to the child', async () => {
|
||||
// A configured DSH_* fact must reach the child: the seam scrubs only the
|
||||
// ambient namespace, and the explicit entry merges after that scrub. The
|
||||
// fixture echoes the named variable back as hover text.
|
||||
const conn = connect({ LSP_FAKE_ECHO_ENV: 'DSH_LSP_TEST_FACT', DSH_LSP_TEST_FACT: 'managed' })
|
||||
await conn.request('initialize', { capabilities: {} })
|
||||
expect(await conn.request('textDocument/hover', {})).toEqual({ contents: 'managed' })
|
||||
|
||||
Reference in New Issue
Block a user