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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

- Upgrades the pinned workflow engine to Smithers 0.32.0, moves both the workspace and the generated runner workspace onto one pinned Effect 4 tree, and migrates existing 0.31.0 manifests forward (#274).
- Fixes durable resume hydration so it runs after the engine resets stale in-progress attempts; upgrading alone would have restored a task as finished while the durable record said pending (#274).
- A partially installed workflow-runner dependency tree now reinstalls itself instead of failing every later resume of a durable run (#274).
- `ultrafuzz doctor` now reports a posture for every workflow-engine compatibility patch instead of only the two CLI patches, and its registry check survives the upstream package rename so the upgrade signal stays alive (#274).
- Adds first-class DeepSeek V4 Pro support through DeepSeek's official Claude
Code endpoint, including cache-aware token telemetry, first-party pricing,
Modal benchmark plumbing, and public benchmark coverage (#163).
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Ultrafuzz is a TypeScript workspace managed with `pnpm`.

The supported host runtime is Node.js `22.19` or newer. This satisfies the
pinned pnpm 11 toolchain, Smithers 0.29.0's Node 22 declaration, and the exact
pinned pnpm 11 toolchain, the pinned Smithers release's Node 22 declaration, and the exact
Kimi Code 0.29.1 CLI used by the adapter contract tests. Smithers' executable
and those contract tests run with Bun 1.3+. The Modal image uses Node.js 22.23.

Expand Down
16 changes: 14 additions & 2 deletions packages/cli/src/commands/doctor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,21 @@ function renderDoctor(value: DoctorValue): string {
`- installed: ${engine.installed_version ?? "not installed"}`,
`- installed bin target: ${engine.installed_bin_target ?? "unknown"}`,
`- local binary: ${engine.bin_path ?? "not present"}`,
`- latest published stable: ${engine.latest_published_version}`,
`- latest published stable: ${engine.latest_published_version}${
engine.latest_published_is_renamed_package ? " (renamed upstream package)" : ""
}`,
`- dependency layout: ${engine.layout_status}${engine.layout_detail === null ? "" : ` - ${engine.layout_detail}`}`,
`- compatibility patches: detached admission ${engine.compatibility_patches.detached_admission}, supervisor descriptor ${engine.compatibility_patches.supervisor_descriptor}`
`- compatibility patches: ${renderCompatibilityPatches(engine.compatibility_patches)}`
];
return `${lines.join("\n")}\n`;
}

// Rendered from whatever the runtime reports rather than a fixed pair of keys, so
// a newly tracked workaround shows up here without a second edit.
function renderCompatibilityPatches(patches: Record<string, string>): string {
const entries = Object.entries(patches);
if (entries.length === 0) {
return "none tracked";
}
return entries.map(([name, posture]) => `${name.replaceAll("_", " ")} ${posture}`).join(", ");
}
13 changes: 13 additions & 0 deletions packages/cli/test/lifecycle-commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ function parseJson(capture: Capture): Record<string, unknown> {

function assertNoEngineBranding(value: unknown): void {
assert.doesNotMatch(JSON.stringify(value), /smithers/iu);
// The engine's successor package name does not contain "smithers", so it slips
// past the scrub by spelling alone. Name it explicitly or the de-branding
// invariant silently stops covering operator-facing engine text.
assert.doesNotMatch(JSON.stringify(value), /smthrs/iu);
}

function writeSmallTopology(project: string): void {
Expand Down Expand Up @@ -478,7 +482,16 @@ test("doctor reports install posture in human and JSON output", async () => {
assert.match(human.stdout + human.stderr, /- bundled: \d+\.\d+\.\d+/u);
assert.match(human.stdout + human.stderr, /- latest published stable: /u);
assert.match(human.stdout + human.stderr, /- compatibility patches: detached admission /u);
// Every tracked workaround has to reach the operator, not just the first one.
// The two resume-durability patches are the ones whose absence silently costs
// durable resume progress, so assert them by name.
assert.match(human.stdout + human.stderr, /- compatibility patches: .*supervisor descriptor /u);
assert.match(human.stdout + human.stderr, /- compatibility patches: .*terminal state restore /u);
assert.match(human.stdout + human.stderr, /- compatibility patches: .*resume hydration /u);
assert.doesNotMatch(human.stdout + human.stderr, /smithers-orchestrator/u);
// The registry check reports the renamed upstream package; it must describe it
// without naming it, on both the human and JSON surfaces.
assert.doesNotMatch(human.stdout + human.stderr, /smthrs/iu);

const json = await cli(project, ["doctor", "--json"], env);
const body = parseJson(json);
Expand Down
7 changes: 4 additions & 3 deletions packages/modal/src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,10 @@ import {
import { getOrCreateModalV2Volume } from "./volume.js";

const DEFAULT_TOOLCHAIN_IMAGE = "ultrafuzz-security-toolchain:latest";
// Smithers 0.31.0 supplies Codex prompts over stdin and uses the `-` stdin
// sentinel. Codex CLI 0.144.3 rejects that form; keep the image pin explicit
// so the runner and standalone Dockerfile cannot silently drift back to it.
// The pinned Smithers release supplies Codex prompts over stdin and uses the `-`
// stdin sentinel, still true in 0.32.0. Codex CLI 0.144.3 rejects that form; keep
// the image pin explicit so the runner and standalone Dockerfile cannot silently
// drift back to it.
export const CODEX_CLI_VERSION = "0.146.0";
const MODAL_RUNTIME_USER = "ubuntu";
const MODAL_RUNTIME_HOME = "/home/ubuntu";
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
"devDependencies": {
"@moonshot-ai/kimi-code": "0.29.1",
"@types/proper-lockfile": "^4.1.4",
"smithers-orchestrator": "0.31.0"
"smithers-orchestrator": "0.32.0"
}
}
104 changes: 98 additions & 6 deletions packages/runtime/src/doctor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { promisify } from "node:util";

import { referencesStatus } from "./references.js";
import { inspectSmithersInstallation, type SmithersInstallationPosture } from "./smithers.js";
import { SMITHERS_ORCHESTRATOR_VERSION } from "./smithers-package.js";
import {
SMITHERS_ORCHESTRATOR_PACKAGE_NAME,
SMITHERS_ORCHESTRATOR_VERSION,
SMITHERS_SUCCESSOR_PACKAGE_NAME
} from "./smithers-package.js";
import type {
DoctorCheck,
DoctorCheckStatus,
Expand Down Expand Up @@ -132,6 +136,10 @@ export async function diagnoseProject(input: DoctorInput) {
installed_bin_target: installation.installed_bin_target,
bin_path: installation.bin_path,
latest_published_version: latest !== undefined && "version" in latest ? latest.version : "unknown",
// The newest release can come from a renamed upstream package, so the version
// above is not necessarily comparable with the pinned one. Flag that rather
// than naming the package, which would leak engine branding.
latest_published_is_renamed_package: latest !== undefined && "version" in latest && latest.renamed,
layout_status: engineCheck.check.status,
layout_detail: installation.layout_error,
compatibility_patches: installation.compatibility_patches
Expand Down Expand Up @@ -272,7 +280,7 @@ function compatibilityPatchCheck(installation: SmithersInstallationPosture): {
};
}

function registryCheck(latest: { version: string } | { error: string } | undefined): {
function registryCheck(latest: LatestPublishedEngine | { error: string } | undefined): {
check: DoctorCheck;
diagnostics: RuntimeDiagnostic[];
} {
Expand Down Expand Up @@ -304,7 +312,29 @@ function registryCheck(latest: { version: string } | { error: string } | undefin
]
};
}
if (latest.version === SMITHERS_ORCHESTRATOR_VERSION) {
// The successor lookup failing while the legacy one succeeds must not read as
// "you are current": the legacy name is frozen at the pinned version forever, so
// that combination is exactly the false positive this check exists to remove.
if (latest.successorUnavailable) {
return {
check: {
name: "workflow-engine-registry",
status: "warning",
summary: "registry lookup was only partly available; a newer workflow engine cannot be ruled out"
},
diagnostics: [
{
code: "DOCTOR_REGISTRY_UNAVAILABLE",
message:
"the pinned workflow engine name is frozen upstream, and the renamed successor package could not be " +
`read, so ${SMITHERS_ORCHESTRATOR_VERSION} cannot be confirmed as current: ${latest.successorUnavailable}`,
severity: "warning",
source: "doctor"
}
]
};
}
if (latest.version === SMITHERS_ORCHESTRATOR_VERSION && !latest.renamed) {
return {
check: {
name: "workflow-engine-registry",
Expand All @@ -314,29 +344,75 @@ function registryCheck(latest: { version: string } | { error: string } | undefin
diagnostics: []
};
}
// Deliberately never names the upstream package: operator-facing text keeps the
// engine de-branded, and the successor name would slip past the `smithers` scrub
// by spelling alone. "renamed upstream package" carries the actionable signal.
const newest = `${latest.version}${latest.renamed ? " under a renamed upstream package" : ""}`;
return {
check: {
name: "workflow-engine-registry",
status: "warning",
summary: `a newer stable workflow engine is published: ${latest.version} (Ultrafuzz pins ${SMITHERS_ORCHESTRATOR_VERSION})`
summary: `a newer stable workflow engine is published: ${newest} (Ultrafuzz pins ${SMITHERS_ORCHESTRATOR_VERSION})`
},
diagnostics: [
{
code: "DOCTOR_WORKFLOW_ENGINE_OUTDATED",
message: `Ultrafuzz pins workflow engine ${SMITHERS_ORCHESTRATOR_VERSION}; ${latest.version} is the latest published stable release`,
message:
`Ultrafuzz pins workflow engine ${SMITHERS_ORCHESTRATOR_VERSION}; ${newest} is the latest published stable release` +
(latest.renamed
? `; upgrading past ${SMITHERS_ORCHESTRATOR_VERSION} requires migrating to the renamed upstream package`
: ""),
severity: "warning",
source: "doctor"
}
]
};
}

interface LatestPublishedEngine {
version: string;
/** True when the newest release comes from the renamed successor package. */
renamed: boolean;
/** Set when the successor lookup failed, so "current" cannot be concluded. */
successorUnavailable?: string;
}

// Upstream renamed the package after the version Ultrafuzz pins, so the old name
// is frozen forever and asking only about it would silently report "you are on the
// latest release" for every future release. Consult both names and report the
// newer. The package names stay inside this module: operator-facing text keeps the
// engine de-branded.
async function latestPublishedSmithersVersion(
projectRoot: string,
env: Record<string, string | undefined>
): Promise<LatestPublishedEngine | { error: string }> {
const [legacy, successor] = await Promise.all([
latestPublishedVersionOf(SMITHERS_ORCHESTRATOR_PACKAGE_NAME, projectRoot, env),
latestPublishedVersionOf(SMITHERS_SUCCESSOR_PACKAGE_NAME, projectRoot, env)
]);
if ("error" in legacy && "error" in successor) {
return { error: legacy.error };
}
if ("error" in successor) {
// `legacy` resolved. Its name can never advance past the pinned version, so an
// unreadable successor leaves the question genuinely open rather than answered.
return { version: (legacy as { version: string }).version, renamed: false, successorUnavailable: successor.error };
}
if ("error" in legacy) {
return { version: successor.version, renamed: true };
}
return compareSemanticVersions(successor.version, legacy.version) > 0
? { version: successor.version, renamed: true }
: { version: legacy.version, renamed: false };
}

async function latestPublishedVersionOf(
packageName: string,
projectRoot: string,
env: Record<string, string | undefined>
): Promise<{ version: string } | { error: string }> {
try {
const { stdout } = await execFileAsync("npm", ["view", "smithers-orchestrator", "dist-tags.latest"], {
const { stdout } = await execFileAsync("npm", ["view", packageName, "dist-tags.latest"], {
cwd: projectRoot,
env: { ...process.env, ...env },
timeout: REGISTRY_LOOKUP_TIMEOUT_MS
Expand All @@ -348,6 +424,22 @@ async function latestPublishedSmithersVersion(
}
}

// Callers only ever pass versions `latestPublishedVersionOf` has already matched
// against `^\d+\.\d+\.\d+$`. That invariant lives in another function, so treat a
// non-numeric segment as 0 rather than returning NaN, which would silently compare
// as "not newer" and reinstate the dead upgrade signal.
function compareSemanticVersions(left: string, right: string): number {
const segment = (value: string, index: number): number => {
const parsed = Number(value.split(".")[index]);
return Number.isFinite(parsed) ? parsed : 0;
};
for (let index = 0; index < 3; index += 1) {
const difference = segment(left, index) - segment(right, index);
if (difference !== 0) return difference;
}
return 0;
}

function configuredAgentRefs(profiles: Record<string, { agent: string }> | undefined): string[] {
return [...new Set(Object.values(profiles ?? {}).map((profile) => profile.agent))].sort();
}
Expand Down
Loading