test(fs): close abort/concurrency/observed coverage gaps + with-key e2e

Behavioral gaps from the coverage audit (line coverage was already 100%; these
close BEHAVIOR gaps):

- fs-local: service-level writeText/editText pre-abort → FS_ABORTED (file
  unchanged); concurrent guarded-write race and mixed write-vs-edit race (one
  wins, one FS_STALE_VERSION, locks released); edit→edit version refresh at the
  provider; the replaceIfVersion post-write version matches a fresh stat. fsio:
  a mid-stream abort → FS_ABORTED (previously only pre-abort was covered).
- fs-policy: the agent-without-session owner rung ({agent:{}} → no owner →
  createIfAbsent / FS_NOT_OBSERVED); fs/write-intent first-wins (symmetric to
  the existing edit-intent test).
- tool-fs: abort-through-the-tool for read/write/edit (isError FS_ABORTED, file
  unchanged); a deterministic tool-tier concurrent-edit race via a shared read;
  the throwing-fs/observed contract (a throwing listener surfaces as isError but
  the mutation already hit disk); the replace_all edit message; parseReadArgs
  rejects fractional/NaN offset and zero/negative limit.
- dsh-fs: FsError chains a cause through ErrorOptions.

New with-key e2e (packages/fs/tool-fs/tests/fs-tools.e2e.ts, self-skips without
DEEPSEEK_API_KEY): a real model drives the real read/write/edit tools to create
→ read → edit a file, verified on disk; a second test proves a relative path
resolves against the per-session cwd (factory meta.cwd) not config.cwd. Booted
via a plain tests/harness.ts. Added dsh-agent-loop + dsh-llm-deepseek devDeps.
This commit is contained in:
Tianyi Cui
2026-07-02 20:38:06 +08:00
parent 94cbec8162
commit b3f8b4c9c6
10 changed files with 348 additions and 0 deletions
@@ -64,6 +64,13 @@ describe('write-intent decision', () => {
expect(await writeIntent(ctx, target('a.txt'), {})).toEqual({ kind: 'createIfAbsent' })
})
it('an actor with an agent but no session has no owner (createIfAbsent)', async () => {
// The middle optional-chain rung: agent present, session undefined ⇒ owner
// undefined ⇒ unobservable, so a write can only be a blind create.
const { ctx } = await setup()
expect(await writeIntent(ctx, target('a.txt'), { agent: {} })).toEqual({ kind: 'createIfAbsent' })
})
it('an observed target decides replaceIfVersion at the observed version', async () => {
const { ctx } = await setup()
const exec = ownerExec({})
@@ -83,6 +90,11 @@ describe('edit-intent decision', () => {
await expect(editIntent(ctx, target('a.txt'), undefined)).rejects.toMatchObject({ code: 'FS_NOT_OBSERVED' })
})
it('rejects an edit whose actor has an agent but no session (no owner)', async () => {
const { ctx } = await setup()
await expect(editIntent(ctx, target('a.txt'), { agent: {} })).rejects.toMatchObject({ code: 'FS_NOT_OBSERVED' })
})
it('returns the observed version as the CAS basis after an observation', async () => {
const { ctx } = await setup()
const exec = ownerExec({})
@@ -166,6 +178,17 @@ describe('single-slot, first-wins', () => {
await editIntent(ctx, target('a.txt'), exec)
expect(secondRan).toBe(false)
})
it('a SECOND write-intent decider registered AFTER fs-policy is not reached', async () => {
const { ctx } = await setup()
let secondRan = false
ctx.on('fs/write-intent', () => {
secondRan = true
return Promise.resolve(undefined)
})
await writeIntent(ctx, target('a.txt'), ownerExec({}))
expect(secondRan).toBe(false)
})
})
describe('disposal releases recorded state (HMR safety)', () => {