Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions LEDGER.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,23 @@ src/index.ts:67-73); the V0 replay fixture is regenerated as a minimal
valid V3 fixture. Acceptance: gate summary per version in the handoff,
each break named with file:line. Release 0.1.3 after acceptance;
dashi W-070 waits on it for lockfile convergence.
Builder note: The first alpha.1 profile failure was a harness assumption,
not a DSH regression: the replay package's caret peers resolved forward,
mixing the alpha.1 loader with alpha.2 dsh-llm. The alpha.1 loader requires
`codec.schema` (`packages/typert/loader/src/index.ts:270-280`), while the
alpha.2 generated discoverModels codec supplies lazy `codec.create`
(`packages/llm/llm/lib/typert.host.js:43-75`). The mixed command
`dsh --profile roller-test 'load roller'` failed with
`parameter codec is not backed by a zod v4 schema`; `pnpm why` showed
dsh-llm-replay alpha.1 selecting dsh-llm alpha.2. There was only Zod 4.4.3,
not a two-major conflict. The throwaway profile now uses time-based resolution
to stay uniform: all 238 DSH packages resolve to alpha.1, the stock
`dsh --profile headless hello` command exits 0, and the packed-profile command
exits 0 with stdout exactly `roller profile loaded`. The same packed command
has the same output on alpha.2. The replay fixture was regenerated as V3
because its V0 form lacked turn/step lifecycle events.
The `profileLines` budget check was removed because deleting `src/version.ts`
left no profile-specific production source to measure.

## Upstream reports

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Install roller into each DSH profile where file rewind should be available:
dsh plugin --profile <name> add @antst/roller
```

Keep every DSH package in a profile on one uniform DSH version.

## Restore files

Run the native DSH command with the event sequence number of a `turn/end`:
Expand Down
19 changes: 11 additions & 8 deletions packages/roller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
"files": [
"lib/**/*.js",
"lib/**/*.d.ts",
"cordis.patch.yml",
"validated-dsh-versions.json"
"cordis.patch.yml"
],
"license": "MIT",
"dsh": {
Expand All @@ -44,28 +43,32 @@
},
"peerDependencies": {
"@deepseek-ai/cordis": "^4.0.2",
"@deepseek-ai/dsh-commands": "0.1.2-rc.1",
"@deepseek-ai/dsh-fs": "0.1.2-rc.1",
"@deepseek-ai/dsh-sandbox": "0.1.2-rc.1",
"@deepseek-ai/dsh-sandbox-policy": "0.1.2-rc.1",
"@deepseek-ai/dsh-session": "0.1.2-rc.1",
"@deepseek-ai/dsh-storage-domain": "0.1.2-rc.1"
"@deepseek-ai/dsh-commands": ">=0.1.5-rc.2",
"@deepseek-ai/dsh-fs": ">=0.1.5-rc.2",
"@deepseek-ai/dsh-sandbox": ">=0.1.5-rc.2",
"@deepseek-ai/dsh-sandbox-policy": ">=0.1.5-rc.2",
"@deepseek-ai/dsh-session": ">=0.1.5-rc.2",
"@deepseek-ai/dsh-storage-domain": ">=0.1.5-rc.2"
},
"devDependencies": {
"@deepseek-ai/cordis": "catalog:",
"@deepseek-ai/dsh-agent": "catalog:",
"@deepseek-ai/dsh-agent-loop": "catalog:",
"@deepseek-ai/dsh-agent-loop-testkit": "catalog:",
"@deepseek-ai/dsh-attachment": "catalog:",
"@deepseek-ai/dsh-commands": "catalog:",
"@deepseek-ai/dsh-fs": "catalog:",
"@deepseek-ai/dsh-fs-local": "catalog:",
"@deepseek-ai/dsh-fs-observation-policy": "catalog:",
"@deepseek-ai/dsh-fs-sandbox": "catalog:",
"@deepseek-ai/dsh-llm": "catalog:",
"@deepseek-ai/dsh-code-runtime": "catalog:",
"@deepseek-ai/dsh-sandbox": "catalog:",
"@deepseek-ai/dsh-sandbox-policy": "catalog:",
"@deepseek-ai/dsh-session": "catalog:",
"@deepseek-ai/dsh-session-persistence": "catalog:",
"@deepseek-ai/dsh-session-projection": "catalog:",
"@deepseek-ai/dsh-settings": "catalog:",
"@deepseek-ai/dsh-storage": "catalog:",
"@deepseek-ai/dsh-storage-domain": "catalog:",
"@deepseek-ai/dsh-storage-json": "catalog:",
Expand Down
4 changes: 0 additions & 4 deletions packages/roller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Context } from '@deepseek-ai/cordis'
import { CaptureJournal } from './capture.js'
import { registerRestoreCommand } from './restore.js'
import { rollerDomainSpec } from './spec.js'
import { warnIfUnsupportedDsh } from './version.js'

export {
MAX_CHECKPOINT_BYTES,
Expand All @@ -18,9 +17,6 @@ export const name = 'roller'
export const inject = ['commands', 'fs', 'sandboxPolicy', 'sessions', 'storageDomain']

export async function apply(ctx: Context): Promise<void> {
// A real profile boot installs Loader before mounting config entries
// (DSH packages/boot/app-boot/src/index.ts:779-789); direct test hosts do not.
if (ctx.get('loader') !== undefined) warnIfUnsupportedDsh()
const domain = await ctx.storageDomain.open(rollerDomainSpec)
ctx.effect(() => () => domain.close())
const journal = new CaptureJournal(ctx, domain.table('checkpoints'))
Expand Down
27 changes: 0 additions & 27 deletions packages/roller/src/version.ts

This file was deleted.

5 changes: 5 additions & 0 deletions packages/roller/tested-dsh-versions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"0.1.5-rc.2",
"0.1.6-alpha.1",
"0.1.6-alpha.2"
]
2 changes: 0 additions & 2 deletions packages/roller/tests/capture.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import LocalFileSystem from '@deepseek-ai/dsh-fs-local'
import * as FsPolicy from '@deepseek-ai/dsh-fs-observation-policy'
import { ToolCallId } from '@deepseek-ai/dsh-llm'
import { SessionId } from '@deepseek-ai/dsh-session'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import SandboxPolicy from '@deepseek-ai/dsh-sandbox-policy'
import Storage from '@deepseek-ai/dsh-storage'
import type { KvTable } from '@deepseek-ai/dsh-storage-domain'
Expand Down Expand Up @@ -45,7 +44,6 @@ async function harness(options: { fsPolicy?: boolean } = {}): Promise<Harness> {
const ctx = new Context()
contexts.push(ctx)

await ctx.plugin(SessionProjectionRegistry)
await mountAgentLoopTestDependencies(ctx)
await ctx.plugin(AgentLoop, { agents: [] })
await ctx.plugin(Commands)
Expand Down
13 changes: 8 additions & 5 deletions packages/roller/tests/fixtures/profile-replay.jsonl
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{"type":"session","version":0,"id":"roller-profile-replay","createdAt":1,"cwd":"/recorded","delegationDepth":0}
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"roller profile loaded"}}}
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"roller profile loaded"}}}}
{"type":"assistant/chunk","data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
{"type":"session","version":3,"id":"roller-profile-replay","createdAt":1,"cwd":"/recorded","isSeeded":false,"delegationDepth":0}
{"type":"turn/start","data":{"turn":1}}
{"type":"step/start","data":{"turn":1,"step":1}}
{"type":"system/message","data":{"turn":1,"step":1,"message":{"role":"system","content":[],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"id":"roller-system"}},"surfaceOp":"append"}
{"type":"user/message","data":{"role":"user","content":[{"type":"text","text":"load roller"}],"source":{"kind":"user"},"id":"roller-user"},"surfaceOp":"append"}
{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"roller profile loaded"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"roller-assistant"},"usage":{"inputTokens":1,"outputTokens":3},"stream":[{"type":"chunk","time":0,"chunk":{"type":"block-start","index":0,"blockType":"text"}},{"type":"text-chunks","time0":0,"index":0,"dt":[],"texts":["roller profile loaded"]},{"type":"chunk","time":0,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"roller profile loaded"}}},{"type":"chunk","time":0,"chunk":{"type":"usage","usage":{"inputTokens":1,"outputTokens":3}}},{"type":"chunk","time":0,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
{"type":"step/end","data":{"turn":1,"step":1}}
{"type":"turn/end","data":{"turn":1,"reason":{"kind":"completed"}}}
20 changes: 8 additions & 12 deletions packages/roller/tests/profile.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const root = resolve(fileURLToPath(new URL('../../..', import.meta.url)))
const dsh = join(root, 'node_modules', '.bin', 'dsh')
const rollerPackage = join(root, 'packages', 'roller')
const replayFixture = join(rollerPackage, 'tests', 'fixtures', 'profile-replay.jsonl')
const { version: dshVersion } = JSON.parse(readFileSync(
join(root, 'node_modules', '@deepseek-ai', 'dsh', 'package.json'), 'utf8',
)) as { version: string }

interface ProcessResult { stdout: string; stderr: string }

Expand All @@ -28,7 +31,7 @@ function run(command: string, args: string[], env: NodeJS.ProcessEnv, cwd = root
}

describe('installed profile', () => {
it('loads in a real headless profile and warns only outside validated versions', () => {
it('loads in a real headless profile', () => {
const directory = mkdtempSync(join(tmpdir(), 'roller-profile-'))
const home = join(directory, 'home')
const env: NodeJS.ProcessEnv = {
Expand Down Expand Up @@ -57,7 +60,8 @@ describe('installed profile', () => {
manifest.dsh.profile.patchReload = 'startup'
writeFileSync(manifestPath, JSON.stringify(manifest, undefined, 2) + '\n')
run('pnpm', [
'add', '--save-exact', '@deepseek-ai/dsh-llm-replay@0.1.2-alpha.5',
'add', '--save-exact', '--config.resolution-mode=time-based',
`@deepseek-ai/dsh-llm-replay@${dshVersion}`,
], env, profileDir)
writeFileSync(join(profileDir, 'cordis.patch.yml'), `
- id: llm-deepseek
Expand All @@ -69,22 +73,14 @@ describe('installed profile', () => {
name: '@deepseek-ai/dsh-llm-replay'
config:
file: !!js process.env.DSH_SNAPSHOT_FILE
providers:
- id: deepseek-official
`)
env.DSH_SNAPSHOT_FILE = replayFixture

const supported = run(dsh, ['--profile', 'roller-test', 'load roller'], env, directory)
expect(supported.stdout).toBe('roller profile loaded\n')
expect(supported.stderr).toBe('')

const allowlist = join(
profileDir, 'node_modules', '@antst', 'roller', 'validated-dsh-versions.json',
)
writeFileSync(allowlist, '[]\n')
const unsupported = run(dsh, ['--profile', 'roller-test', 'load roller'], env, directory)
expect(unsupported.stdout).toBe('roller profile loaded\n')
expect(unsupported.stderr).toBe(
'roller: warning: DSH 0.1.2-rc.1 is not validated; validated: \n',
)
} finally {
rmSync(directory, { recursive: true, force: true })
}
Expand Down
2 changes: 0 additions & 2 deletions packages/roller/tests/restore.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import * as FsPolicy from '@deepseek-ai/dsh-fs-observation-policy'
import SandboxedFileSystem from '@deepseek-ai/dsh-fs-sandbox'
import { ToolCallId } from '@deepseek-ai/dsh-llm'
import { SessionId, SessionSeq } from '@deepseek-ai/dsh-session'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import SandboxPolicy, { setSandboxMode } from '@deepseek-ai/dsh-sandbox-policy'
import Storage from '@deepseek-ai/dsh-storage'
import type { KvTable } from '@deepseek-ai/dsh-storage-domain'
Expand Down Expand Up @@ -68,7 +67,6 @@ async function harness(options: { sandboxed?: boolean } = {}): Promise<Harness>
roots.push(root, storageRoot)
const ctx = new Context()
contexts.push(ctx)
await ctx.plugin(SessionProjectionRegistry)
await mountAgentLoopTestDependencies(ctx)
await ctx.plugin(AgentLoop, { agents: [] })
await ctx.plugin(Commands)
Expand Down
3 changes: 0 additions & 3 deletions packages/roller/validated-dsh-versions.json

This file was deleted.

Loading
Loading