test: close per-file coverage gaps opened by the message-machine refactor

Downstream packages lost the tests that exercised their agent-loop-facing
edges when the loop was rewritten. Restore 100% per-file coverage with
behavior tests through public seams: llm-retry config validation and
cancellation races, goal replay drift/staleness/teardown edges, plan-mode
disposed-flush, workspace-context empty-change commits, api-proxy
synchronous send failures, acp-snapshot spill-path extraction and refresh
write-back, ACP injection-triggered turns, cli-demo and tui inbox
lifecycle edges, and agent-loop retry/settlement/lifecycle branches.
The only source changes are narrowly-justified v8 ignore annotations on
invariant guards and one redundant-guard removal (workspace-context).
This commit is contained in:
_Kerman
2026-07-26 11:49:19 +08:00
parent 8432c68b6a
commit af3311e1f6
16 changed files with 940 additions and 5 deletions

View File

@@ -358,6 +358,9 @@ export function applyGoalEvent(state: GoalFoldState, event: SessionEvent): GoalC
if (source === undefined) return undefined
// A goal-sourced message without a change must be a positive-round
// admitted continuation prompt; round zero owes a durable source change.
/* v8 ignore next 3 -- decodeGoalEvent returns the change or fails loud for every
round-zero goal source, so only positive rounds reach here; the guard keeps
replay fail-loud against a decoder change */
if (source.round === 0) {
throw new Error(`goal source at session event ${event.seq} lacks goal change data`)
}

View File

@@ -821,6 +821,12 @@ describe('goal replay validation', () => {
expect(() => foldGoal(oneChange(change, {
source: { kind: 'goal', goalId: change.goal.id, revision: 1, round: -1 },
}))).toThrow('source is invalid')
expect(() => foldGoal(oneChange(change, {
source: { kind: 'goal', goalId: GoalId('goal-imposter'), revision: 1, round: 0, change },
}))).toThrow('mismatched source attribution')
expect(() => foldGoal(oneChange(change, {
source: { kind: 'goal', goalId: change.goal.id, revision: 2, round: 0, change },
}))).toThrow('mismatched source attribution')
expect(() => foldGoal(oneChange(change, { content: [{ type: 'text', text: 'wrong' }] }))).toThrow('model-visible content')
})