Skip to content

Commit ff0fc86

Browse files
Cobb04codex
andcommitted
fix(dsh): align configured assets with native parity
Align raw Instruction render-budget accounting and DSH home normalization with qualified DSH 0.1.1-rc.2. Addresses maintainer review for Story #101 using docs/specs/2026-08-23-101-deepseek-harness-configured-assets.md. The change was validated with Node 22.20 and Node 24 focused suites, both pinned native DSH smokes, and the full repository validation sequence with an extended local Vitest timeout for the isolated artifact test. Co-authored-by: Codex (GPT 5.6 Sol) <codex@openai.com>
1 parent 7ee924b commit ff0fc86

4 files changed

Lines changed: 240 additions & 14 deletions

File tree

docs/specs/2026-08-23-101-deepseek-harness-configured-assets.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- Spec ID: deepseek-harness-configured-assets
66
- Story: #101
7-
- Status: Draft
7+
- Status: Implemented
88
- Approved scope: [Issue #101](https://github.com/QoderAI/better-harness/issues/101)
99
- Qualified DSH release: `0.1.1-rc.2`
1010
- Qualified DSH source: `b150a551b8d465e31e418e1b2eaf5e79bbb7d28e`
@@ -139,8 +139,12 @@ user-home opt-in.
139139

140140
Explicit-root scope is `project` inside workspace, `user` inside the operating
141141
system home, and `other` otherwise. Relative custom/bundled/agents-home values
142-
resolve from `process.cwd()` and do not expand literal `~`; DSH home uses DSH's
143-
supported tilde expansion.
142+
resolve from `process.cwd()` and do not expand literal `~`. DSH home alone uses
143+
native `resolveDshHome` semantics: an explicit `dshHome`/`dsh-home`/`home`
144+
value has precedence (including an explicit blank value); a blank or
145+
whitespace-only ambient `DSH_HOME` is treated as unset and falls back to
146+
`<operating-system-home>/.dsh`; and `~`, `~/`, and `~\` prefixes expand against
147+
the operating-system home.
144148

145149
### AC-8: Native Instruction discovery and order
146150

@@ -166,9 +170,10 @@ file symlink is followed. Stat size and streaming UTF-8 byte count enforce
166170
and non-file candidates are excluded independently without collapsing other
167171
Instruction sources.
168172

169-
Loaded content is trimmed, SHA-1 hashed, and deduplicated only within the same
173+
Loaded raw content is preserved for native render-byte budgeting. A SHA-1
174+
digest of the trimmed content is used only for deduplication within the same
170175
`dirname(displayPath)`. The earliest same-directory duplicate wins; identical
171-
content in different directories remains. Content and digests are never
176+
content in different directories remains. Raw content and digests are never
172177
serialized.
173178

174179
### AC-10: Aggregate Instruction budget

scripts/agent-customize/providers/dsh.mjs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ const COMPACT_WORKSPACE_CONTEXT_INTRO = "Workspace instructions were omitted or
2525

2626
function expandDshHome(value) {
2727
if (value === "~") return os.homedir();
28-
if (value.startsWith("~/")) return path.join(os.homedir(), value.slice(2));
28+
if (value.startsWith("~/") || value.startsWith("~\\")) {
29+
return path.join(os.homedir(), value.slice(2));
30+
}
2931
return value;
3032
}
3133

@@ -474,7 +476,7 @@ async function readBoundedInstruction(candidate, maxSourceBytes, diagnostics) {
474476
});
475477
return undefined;
476478
}
477-
return { ...candidate, content: chunks.join("").trim() };
479+
return { ...candidate, content: chunks.join("") };
478480
}
479481

480482
function instructionDigest(content) {
@@ -694,8 +696,13 @@ export async function collectDshCustomizeInventory(options = {}) {
694696
await requireDirectory(workspace, "workspace");
695697
await requireDirectory(cwd, "cwd");
696698

697-
const dshHomeInput = options.dshHome ?? options["dsh-home"] ?? options.home
698-
?? process.env.DSH_HOME ?? path.join(os.homedir(), ".dsh");
699+
const explicitDshHome = options.dshHome ?? options["dsh-home"] ?? options.home;
700+
const environmentDshHome = process.env.DSH_HOME;
701+
const dshHomeInput = explicitDshHome ?? (
702+
environmentDshHome !== undefined && environmentDshHome.trim().length > 0
703+
? environmentDshHome
704+
: path.join(os.homedir(), ".dsh")
705+
);
699706
const dshHome = path.resolve(expandDshHome(dshHomeInput));
700707
const dshAgentsHome = path.resolve(
701708
options.dshAgentsHome ?? process.env.DSH_AGENTS_HOME ?? path.join(os.homedir(), ".agents"),

scripts/dsh-configured-assets/native-smoke.mjs

Lines changed: 120 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env node
22

33
import assert from "node:assert/strict";
4-
import { spawn } from "node:child_process";
4+
import { spawn, spawnSync } from "node:child_process";
55
import {
66
access,
77
mkdir,
@@ -81,13 +81,17 @@ async function directorySkill(root, entry, name, description) {
8181
return filePath;
8282
}
8383

84-
async function loadPackage(nodeModules, packageName) {
84+
async function packageEntryPath(nodeModules, packageName) {
8585
const packageRoot = path.join(nodeModules, ...packageName.split("/"));
8686
const manifest = JSON.parse(await readFile(path.join(packageRoot, "package.json"), "utf8"));
8787
if (packageName.startsWith("@deepseek-ai/dsh-")) {
8888
assert.equal(manifest.version, DSH_NATIVE_VERSION, `${packageName} must remain pinned`);
8989
}
90-
return import(pathToFileURL(path.join(packageRoot, manifest.main ?? "lib/index.js")));
90+
return path.join(packageRoot, manifest.main ?? "lib/index.js");
91+
}
92+
93+
async function loadPackage(nodeModules, packageName) {
94+
return import(pathToFileURL(await packageEntryPath(nodeModules, packageName)));
9195
}
9296

9397
async function createFixture(scratch) {
@@ -100,8 +104,18 @@ async function createFixture(scratch) {
100104
const customTwo = path.join(scratch, "custom-two");
101105
const bundled = path.join(scratch, "bundled");
102106
const external = path.join(scratch, "external targets");
107+
const budgetRepository = path.join(scratch, "budget repo");
108+
const budgetCwd = path.join(budgetRepository, "nested");
109+
const normalizationRepository = path.join(scratch, "normalization repo");
110+
const normalizationCwd = path.join(normalizationRepository, "workspace");
111+
const syntheticHome = path.join(scratch, "synthetic home");
103112
await mkdir(path.join(repository, ".git"), { recursive: true });
104113
await mkdir(cwd, { recursive: true });
114+
await mkdir(path.join(budgetRepository, ".git"), { recursive: true });
115+
await mkdir(budgetCwd, { recursive: true });
116+
await mkdir(path.join(normalizationRepository, ".git"), { recursive: true });
117+
await mkdir(normalizationCwd, { recursive: true });
118+
await mkdir(syntheticHome, { recursive: true });
105119

106120
await directorySkill(path.join(repository, ".dsh", "skills"), "alpha", "alpha", "project dsh");
107121
await write(path.join(repository, ".dsh", "skills", "flat.md"), skill("flat-skill", "flat"));
@@ -152,6 +166,8 @@ async function createFixture(scratch) {
152166
await write(path.join(workspace, "CLAUDE.md"), " SAME API INSTRUCTION \n");
153167
await write(path.join(workspace, "AGENTS.local.md"), "API LOCAL INSTRUCTION");
154168
await write(path.join(cwd, "AGENTS.md"), "🙂".repeat(2_000));
169+
await write(path.join(budgetRepository, "AGENTS.md"), `ROOT${" ".repeat(400)}`);
170+
await write(path.join(budgetCwd, "AGENTS.md"), `LEAF${" ".repeat(400)}`);
155171

156172
return {
157173
repository,
@@ -164,9 +180,68 @@ async function createFixture(scratch) {
164180
bundled,
165181
external,
166182
symlinkCases,
183+
budgetRepository,
184+
budgetCwd,
185+
normalizationCwd,
186+
syntheticHome,
167187
};
168188
}
169189

190+
async function probeHomeNormalization(nodeModules, fixture) {
191+
const nativeHomePath = await packageEntryPath(nodeModules, "@deepseek-ai/dsh-home-paths");
192+
const cases = [
193+
{ label: "blank environment", envDshHome: "" },
194+
{ label: "whitespace environment", envDshHome: " " },
195+
{ label: "forward-slash environment tilde", envDshHome: "~/dsh-test" },
196+
{ label: "backslash environment tilde", envDshHome: "~\\dsh-test" },
197+
{ label: "explicit backslash tilde", envDshHome: "~/environment-home", explicitDshHome: "~\\dsh-test" },
198+
{ label: "explicit blank", envDshHome: "~/environment-home", explicitDshHome: "" },
199+
];
200+
const script = [
201+
`const NativeHome = await import(${JSON.stringify(pathToFileURL(nativeHomePath).href)});`,
202+
`const BetterHarness = await import(${JSON.stringify(pathToFileURL(AGENT_CUSTOMIZE_PATH).href)});`,
203+
`const cases = ${JSON.stringify(cases)};`,
204+
`const baseOptions = ${JSON.stringify({
205+
provider: "dsh",
206+
workspace: fixture.normalizationCwd,
207+
cwd: fixture.normalizationCwd,
208+
dshAgentsHome: path.join(fixture.syntheticHome, ".agents"),
209+
includeUserHome: false,
210+
})};`,
211+
"const results = [];",
212+
"for (const current of cases) {",
213+
" process.env.DSH_HOME = current.envDshHome;",
214+
" const configured = Object.hasOwn(current, 'explicitDshHome') ? current.explicitDshHome : undefined;",
215+
" const native = NativeHome.resolveDshHome(configured, process.env);",
216+
" const options = { ...baseOptions };",
217+
" if (Object.hasOwn(current, 'explicitDshHome')) options.dshHome = current.explicitDshHome;",
218+
" const inventory = await BetterHarness.collectAgentCustomizeInventory(options);",
219+
" results.push({ label: current.label, native, betterHarness: inventory.dshHome });",
220+
"}",
221+
"process.stdout.write(JSON.stringify({ cwd: process.cwd(), results }));",
222+
].join("\n");
223+
const result = spawnSync(process.execPath, ["--input-type=module", "--eval", script], {
224+
cwd: fixture.normalizationCwd,
225+
encoding: "utf8",
226+
env: {
227+
...process.env,
228+
HOME: fixture.syntheticHome,
229+
USERPROFILE: fixture.syntheticHome,
230+
},
231+
});
232+
assert.equal(result.status, 0, result.stderr);
233+
const probe = JSON.parse(result.stdout);
234+
assert.deepEqual(probe.results.map((entry) => entry.native), [
235+
path.join(fixture.syntheticHome, ".dsh"),
236+
path.join(fixture.syntheticHome, ".dsh"),
237+
path.join(fixture.syntheticHome, "dsh-test"),
238+
path.join(fixture.syntheticHome, "dsh-test"),
239+
path.join(fixture.syntheticHome, "dsh-test"),
240+
probe.cwd,
241+
]);
242+
return probe;
243+
}
244+
170245
async function verifyNativeOwners(nodeModules, fixture) {
171246
const { Context } = await loadPackage(nodeModules, "@deepseek-ai/cordis");
172247
const { default: SkillRegistry } = await loadPackage(nodeModules, "@deepseek-ai/dsh-skill");
@@ -252,18 +327,34 @@ async function verifyNativeOwners(nodeModules, fixture) {
252327
assert.ok(budgeted.omitted.length > 0 || budgeted.truncated.length > 0);
253328
assert.doesNotMatch(budgeted.text, //u);
254329

330+
const whitespaceBudgeted = await Instructions.loadBaselineInstructions({
331+
cwd: fixture.budgetCwd,
332+
maxSourceBytes: 1_048_576,
333+
maxBytes: 512,
334+
});
335+
assert.ok(whitespaceBudgeted);
336+
assert.equal(Buffer.byteLength(`ROOT${" ".repeat(400)}`, "utf8"), 404);
337+
assert.equal(Buffer.byteLength(`LEAF${" ".repeat(400)}`, "utf8"), 404);
338+
const whitespaceBudgetRules = ["AGENTS.md", path.join("nested", "AGENTS.md")].filter((displayPath) => (
339+
whitespaceBudgeted.text.includes(`Instructions from: ${displayPath}`)
340+
));
341+
assert.deepEqual(whitespaceBudgetRules, [path.join("nested", "AGENTS.md")]);
342+
assert.ok(whitespaceBudgeted.omitted.length > 0);
343+
assert.ok(whitespaceBudgeted.truncated.length > 0);
344+
255345
return {
256346
skillNames,
257347
instructionCandidates: discovered.map((file) => file.displayPath),
258348
deduplicatedApiClaude: !full.text.includes(`Instructions from: ${path.join("packages", "api", "CLAUDE.md")}`),
259349
sourceLimit: "verified",
260350
aggregateBudget: "verified",
351+
whitespaceBudgetRules,
261352
utf8: "verified",
262353
symlinkCases: fixture.symlinkCases,
263354
};
264355
}
265356

266-
async function compareBetterHarness(fixture, native) {
357+
async function compareBetterHarness(fixture, native, homeNormalization) {
267358
try {
268359
await access(AGENT_CUSTOMIZE_PATH);
269360
} catch {
@@ -326,6 +417,28 @@ async function compareBetterHarness(fixture, native) {
326417
assert.ok(budgeted.diagnostics.instructionDecisions.some((entry) => (
327418
entry.reason === "budget-omitted" || entry.reason === "budget-truncated"
328419
)));
420+
421+
const whitespaceBudgeted = await collectAgentCustomizeInventory({
422+
provider: "dsh",
423+
workspace: fixture.budgetCwd,
424+
cwd: fixture.budgetCwd,
425+
maxBytes: 512,
426+
maxSourceBytes: 1_048_576,
427+
});
428+
assert.deepEqual(
429+
whitespaceBudgeted.manage.rules.map((entry) => entry.name),
430+
native.whitespaceBudgetRules,
431+
);
432+
assert.ok(whitespaceBudgeted.diagnostics.instructionDecisions.some((entry) => (
433+
entry.path === "AGENTS.md" && entry.reason === "budget-omitted"
434+
)));
435+
assert.ok(whitespaceBudgeted.diagnostics.instructionDecisions.some((entry) => (
436+
entry.path === path.join("nested", "AGENTS.md") && entry.reason === "budget-truncated"
437+
)));
438+
assert.doesNotMatch(JSON.stringify(whitespaceBudgeted), /ROOT|LEAF/u);
439+
for (const entry of homeNormalization.results) {
440+
assert.equal(entry.betterHarness, entry.native, entry.label);
441+
}
329442
assert.doesNotMatch(JSON.stringify(optedIn), /NATIVE PRIVATE SKILL BODY|NATIVE INSTRUCTION|SAME API INSTRUCTION/u);
330443
}
331444

@@ -345,16 +458,18 @@ try {
345458
scratch = await mkdtemp(path.join(os.tmpdir(), "better-harness-dsh-assets-smoke-"));
346459
const fixture = await createFixture(scratch);
347460
const native = await verifyNativeOwners(installation, fixture);
461+
const homeNormalization = await probeHomeNormalization(installation, fixture);
348462
process.stdout.write(`${JSON.stringify({
349463
phase: "native-dsh",
350464
status: "pass",
351465
dshVersion: DSH_NATIVE_VERSION,
352466
sourceSha: DSH_NATIVE_SOURCE_SHA,
353467
credentialUsed: false,
354468
platform: process.platform,
469+
homeNormalization: "verified",
355470
...native,
356471
})}\n`);
357-
await compareBetterHarness(fixture, native);
472+
await compareBetterHarness(fixture, native, homeNormalization);
358473
process.stdout.write(`${JSON.stringify({ phase: "better-harness-comparison", status: "pass" })}\n`);
359474
} finally {
360475
if (scratch) await rm(scratch, { recursive: true, force: true });

0 commit comments

Comments
 (0)