@nowcrew/daemon 0.6.10 → 0.6.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -440,8 +440,6 @@ const materializeWorkspaceTraining = async (agentsRoot, handle, ability) => {
|
|
|
440
440
|
for (const mount of mounts) {
|
|
441
441
|
const sources = verified.files.filter((file) => file.path.endsWith(".md")
|
|
442
442
|
&& (file.path === mount.path || file.path.startsWith(`${mount.path}/`)));
|
|
443
|
-
if (sources.length === 0)
|
|
444
|
-
throw new Error(`ability_memory_mount_empty:${mount.path}`);
|
|
445
443
|
for (const source of sources) {
|
|
446
444
|
const relativePath = source.path === mount.path
|
|
447
445
|
? source.path.split("/").at(-1)
|
|
@@ -467,7 +465,10 @@ const materializeWorkspaceTraining = async (agentsRoot, handle, ability) => {
|
|
|
467
465
|
: join(sourceRoot, asset.source);
|
|
468
466
|
await cp(source, target, { recursive: true, preserveTimestamps: true });
|
|
469
467
|
}
|
|
470
|
-
const evalPaths = [
|
|
468
|
+
const evalPaths = [
|
|
469
|
+
...(verified.manifest.spec.evals.policy === undefined ? [] : [verified.manifest.spec.evals.policy]),
|
|
470
|
+
...verified.manifest.spec.evals.cases,
|
|
471
|
+
];
|
|
471
472
|
for (const path of evalPaths) {
|
|
472
473
|
const target = join(staging, "evals", layerRelativePath(path, "evals"));
|
|
473
474
|
await mkdir(dirname(target), { recursive: true });
|
|
@@ -253,9 +253,19 @@ const scan = (files, manifest) => {
|
|
|
253
253
|
if (executable.has(extname(file.path).toLowerCase()))
|
|
254
254
|
findings.push({ code: "executable_asset", path: file.path });
|
|
255
255
|
}
|
|
256
|
-
const required = new Set(["instructions"
|
|
256
|
+
const required = new Set(["instructions"]);
|
|
257
257
|
if (manifest.spec.skills.length > 0)
|
|
258
258
|
required.add("skills");
|
|
259
|
+
if (manifest.spec.memory.policy.length > 0)
|
|
260
|
+
required.add("memory-policy");
|
|
261
|
+
if (manifest.spec.memory.seeds.length > 0)
|
|
262
|
+
required.add("memory-seed");
|
|
263
|
+
if (manifest.spec.workspace.assets.length > 0)
|
|
264
|
+
required.add("workspace");
|
|
265
|
+
if (manifest.spec.evals.policy !== undefined)
|
|
266
|
+
required.add("eval-policy");
|
|
267
|
+
if (manifest.spec.evals.cases.length > 0)
|
|
268
|
+
required.add("eval-cases");
|
|
259
269
|
return { findings, required };
|
|
260
270
|
};
|
|
261
271
|
const lockedManifestPaths = (manifest) => [
|
|
@@ -264,7 +274,7 @@ const lockedManifestPaths = (manifest) => [
|
|
|
264
274
|
...manifest.spec.memory.policy.map((entry) => entry.path),
|
|
265
275
|
...manifest.spec.memory.seeds.map((entry) => entry.path),
|
|
266
276
|
...manifest.spec.workspace.assets.map((entry) => entry.source),
|
|
267
|
-
manifest.spec.evals.policy,
|
|
277
|
+
...(manifest.spec.evals.policy === undefined ? [] : [manifest.spec.evals.policy]),
|
|
268
278
|
...manifest.spec.evals.cases,
|
|
269
279
|
];
|
|
270
280
|
export const evaluateAbilityCases = (files, manifest, lock, memory) => {
|
|
@@ -367,7 +377,7 @@ export async function resolveAbilityRelease(agentsRoot, command) {
|
|
|
367
377
|
const assertions = [
|
|
368
378
|
{ name: "manifest_lock_verified", passed: true },
|
|
369
379
|
{ name: "manifest_asset_paths_locked", passed: lockedManifestPaths(manifest).every((path) => lockedPaths.has(path)) },
|
|
370
|
-
{ name: "
|
|
380
|
+
{ name: "declared_layers_resolvable", passed: [...security.required].every((kind) => kind === "skills" ? kinds.has(kind) || (manifest.spec.skills.length > 0 && lock.dependencies.length > 0) : kinds.has(kind)) },
|
|
371
381
|
{ name: "dependencies_pinned", passed: lock.dependencies.every((dependency) => /^[a-f0-9]{40}$/u.test(dependency.commit)) },
|
|
372
382
|
{ name: "security_scan_clear", passed: security.findings.length === 0 },
|
|
373
383
|
...evaluateAbilityCases(files, manifest, lock, memory),
|
|
@@ -61,16 +61,20 @@ export const DaemonAbilityManifestSchema = z.object({
|
|
|
61
61
|
skills: z.array(z.object({
|
|
62
62
|
name: z.string().min(1).max(128), source: z.union([LocalSkillSchema, GitSkillSchema]),
|
|
63
63
|
mount: SafeAbilityPathSchema, mode: ModeSchema, trust: z.string().max(128).optional(),
|
|
64
|
-
}).strict()).max(500),
|
|
64
|
+
}).strict()).max(500).default([]),
|
|
65
65
|
memory: z.object({
|
|
66
|
-
policy: z.array(z.object({ path: SafeAbilityPathSchema, mode: ModeSchema, mergeKey: z.string().optional() }).strict()).max(100),
|
|
67
|
-
seeds: z.array(z.object({ path: SafeAbilityPathSchema, mode: ModeSchema, mergeKey: z.string().optional() }).strict()).max(1_000),
|
|
68
|
-
runtime: z.object({ store: z.literal("nowcrew-managed"), promotion: z.literal("pull-request"), retentionDays: z.number().int().positive().optional() }).strict()
|
|
69
|
-
|
|
66
|
+
policy: z.array(z.object({ path: SafeAbilityPathSchema, mode: ModeSchema, mergeKey: z.string().optional() }).strict()).max(100).default([]),
|
|
67
|
+
seeds: z.array(z.object({ path: SafeAbilityPathSchema, mode: ModeSchema, mergeKey: z.string().optional() }).strict()).max(1_000).default([]),
|
|
68
|
+
runtime: z.object({ store: z.literal("nowcrew-managed"), promotion: z.literal("pull-request"), retentionDays: z.number().int().positive().optional() }).strict()
|
|
69
|
+
.default({ store: "nowcrew-managed", promotion: "pull-request" }),
|
|
70
|
+
}).strict().default({ policy: [], seeds: [], runtime: { store: "nowcrew-managed", promotion: "pull-request" } }),
|
|
70
71
|
workspace: z.object({ assets: z.array(z.object({
|
|
71
72
|
source: SafeAbilityPathSchema, target: WorkspaceAbilityTargetSchema, mode: ModeSchema,
|
|
72
|
-
}).strict()).max(1_000) }).strict(),
|
|
73
|
-
evals: z.object({
|
|
73
|
+
}).strict()).max(1_000).default([]) }).strict().default({ assets: [] }),
|
|
74
|
+
evals: z.object({
|
|
75
|
+
policy: SafeAbilityPathSchema.optional(),
|
|
76
|
+
cases: z.array(SafeAbilityPathSchema).max(1_000).default([]),
|
|
77
|
+
}).strict().default({ cases: [] }),
|
|
74
78
|
compatibility: z.object({
|
|
75
79
|
providers: z.array(z.enum(["claude", "codex", "kimi", "hermes", "opencode", "deepseek-harness"])).min(1),
|
|
76
80
|
minNowCrewVersion: z.string().regex(/^\d+\.\d+\.\d+$/u),
|
package/dist/local-executor.js
CHANGED
|
@@ -788,6 +788,16 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
788
788
|
changes_truncated: changesTruncated,
|
|
789
789
|
evidence_complete: noteDiff.evidence_complete
|
|
790
790
|
&& !changesTruncated,
|
|
791
|
+
before_manifest_error: noteDiff.before_manifest.error,
|
|
792
|
+
after_manifest_error: noteDiff.after_manifest.error,
|
|
793
|
+
before_manifest_truncated: noteDiff.before_manifest.truncated,
|
|
794
|
+
after_manifest_truncated: noteDiff.after_manifest.truncated,
|
|
795
|
+
before_total_count: noteDiff.before_manifest.total_count,
|
|
796
|
+
after_total_count: noteDiff.after_manifest.total_count,
|
|
797
|
+
before_omitted_count: noteDiff.before_manifest.omitted_count,
|
|
798
|
+
after_omitted_count: noteDiff.after_manifest.omitted_count,
|
|
799
|
+
before_incomplete_file_count: noteDiff.before_manifest.incomplete_file_count,
|
|
800
|
+
after_incomplete_file_count: noteDiff.after_manifest.incomplete_file_count,
|
|
791
801
|
changes: serializedChanges.json,
|
|
792
802
|
});
|
|
793
803
|
const postcondition = evaluateMemoryPrunePostcondition(memoryPruneBeforeSnapshot, snapshot, {
|
|
@@ -266,45 +266,69 @@ function fileChanged(before, after) {
|
|
|
266
266
|
}
|
|
267
267
|
return before.size !== after.size || before.mtime_ms !== after.mtime_ms;
|
|
268
268
|
}
|
|
269
|
+
function notePresence(file) {
|
|
270
|
+
if (file === undefined)
|
|
271
|
+
return "absent";
|
|
272
|
+
if (file.exists)
|
|
273
|
+
return "present";
|
|
274
|
+
if (!file.exists && (file.error === undefined || file.error === "ENOENT"))
|
|
275
|
+
return "absent";
|
|
276
|
+
return "unknown";
|
|
277
|
+
}
|
|
269
278
|
export function diffMemoryPruneNotes(before, after) {
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
.filter((file) => file.exists
|
|
275
|
-
|
|
279
|
+
const manifestDiagnostics = (manifest) => ({
|
|
280
|
+
total_count: manifest.total_count,
|
|
281
|
+
omitted_count: manifest.omitted_count,
|
|
282
|
+
truncated: manifest.truncated,
|
|
283
|
+
incomplete_file_count: manifest.files.filter((file) => !file.exists
|
|
284
|
+
|| file.sha256 === undefined
|
|
285
|
+
|| file.error !== undefined
|
|
286
|
+
|| file.hash_skipped_reason !== undefined).length,
|
|
287
|
+
...(manifest.error === undefined ? {} : { error: manifest.error }),
|
|
288
|
+
});
|
|
289
|
+
const beforeDiagnostics = manifestDiagnostics(before);
|
|
290
|
+
const afterDiagnostics = manifestDiagnostics(after);
|
|
291
|
+
const beforeByPath = new Map(before.files.map((file) => [file.relative_path, file]));
|
|
292
|
+
const afterByPath = new Map(after.files.map((file) => [file.relative_path, file]));
|
|
276
293
|
const paths = [...new Set([...beforeByPath.keys(), ...afterByPath.keys()])]
|
|
277
294
|
.sort(compareCodeUnits);
|
|
278
295
|
const allChanges = [];
|
|
279
|
-
|
|
280
|
-
const
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
296
|
+
if (before.error === undefined && after.error === undefined) {
|
|
297
|
+
const presenceDiffIsReliable = !before.truncated && !after.truncated;
|
|
298
|
+
for (const relativePath of paths) {
|
|
299
|
+
const beforeFile = beforeByPath.get(relativePath);
|
|
300
|
+
const afterFile = afterByPath.get(relativePath);
|
|
301
|
+
const beforePresence = notePresence(beforeFile);
|
|
302
|
+
const afterPresence = notePresence(afterFile);
|
|
303
|
+
if (presenceDiffIsReliable && beforePresence === "absent" && afterPresence === "present"
|
|
304
|
+
&& afterFile !== undefined) {
|
|
305
|
+
allChanges.push({
|
|
306
|
+
relative_path: relativePath,
|
|
307
|
+
change: "created",
|
|
308
|
+
...(afterFile.sha256 === undefined ? {} : { after_sha256: afterFile.sha256 }),
|
|
309
|
+
...(afterFile.size === undefined ? {} : { after_size: afterFile.size }),
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
else if (presenceDiffIsReliable && beforePresence === "present" && afterPresence === "absent"
|
|
313
|
+
&& beforeFile !== undefined) {
|
|
314
|
+
allChanges.push({
|
|
315
|
+
relative_path: relativePath,
|
|
316
|
+
change: "deleted",
|
|
317
|
+
...(beforeFile.sha256 === undefined ? {} : { before_sha256: beforeFile.sha256 }),
|
|
318
|
+
...(beforeFile.size === undefined ? {} : { before_size: beforeFile.size }),
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
else if (beforePresence === "present" && afterPresence === "present"
|
|
322
|
+
&& beforeFile !== undefined && afterFile !== undefined && fileChanged(beforeFile, afterFile)) {
|
|
323
|
+
allChanges.push({
|
|
324
|
+
relative_path: relativePath,
|
|
325
|
+
change: "updated",
|
|
326
|
+
...(beforeFile.sha256 === undefined ? {} : { before_sha256: beforeFile.sha256 }),
|
|
327
|
+
...(afterFile.sha256 === undefined ? {} : { after_sha256: afterFile.sha256 }),
|
|
328
|
+
...(beforeFile.size === undefined ? {} : { before_size: beforeFile.size }),
|
|
329
|
+
...(afterFile.size === undefined ? {} : { after_size: afterFile.size }),
|
|
330
|
+
});
|
|
331
|
+
}
|
|
308
332
|
}
|
|
309
333
|
}
|
|
310
334
|
return {
|
|
@@ -315,10 +339,12 @@ export function diffMemoryPruneNotes(before, after) {
|
|
|
315
339
|
&& after.error === undefined
|
|
316
340
|
&& !before.truncated
|
|
317
341
|
&& !after.truncated
|
|
318
|
-
&&
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
342
|
+
&& before.omitted_count === 0
|
|
343
|
+
&& after.omitted_count === 0
|
|
344
|
+
&& beforeDiagnostics.incomplete_file_count === 0
|
|
345
|
+
&& afterDiagnostics.incomplete_file_count === 0,
|
|
346
|
+
before_manifest: beforeDiagnostics,
|
|
347
|
+
after_manifest: afterDiagnostics,
|
|
322
348
|
};
|
|
323
349
|
}
|
|
324
350
|
export function evaluateMemoryPrunePostcondition(before, after, execution) {
|