agent-hitch 0.2.12 → 0.2.14
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.
- package/benchmark-packages/automationbench/RESOURCES.md +27 -0
- package/benchmark-packages/automationbench/resources.mjs +86 -0
- package/benchmark-packages/shared-tree/README.md +14 -0
- package/benchmark-packages/shared-tree/import.mjs +39 -0
- package/dist/scripts/canary-automation-resources.js +86 -0
- package/dist/scripts/canary-automation-resources.js.map +1 -0
- package/dist/scripts/canary-resource-empty-daemon.js +195 -0
- package/dist/scripts/canary-resource-empty-daemon.js.map +1 -0
- package/dist/scripts/canary-resources.js +89 -0
- package/dist/scripts/canary-resources.js.map +1 -0
- package/dist/scripts/check-architecture.js +6 -5
- package/dist/scripts/check-architecture.js.map +1 -1
- package/dist/scripts/resource-space-sampler.js +83 -0
- package/dist/scripts/resource-space-sampler.js.map +1 -0
- package/dist/src/adapters/providers/shared.js +0 -1
- package/dist/src/adapters/providers/shared.js.map +1 -1
- package/dist/src/backends/harbor/backend.js +5 -1
- package/dist/src/backends/harbor/backend.js.map +1 -1
- package/dist/src/backends/harbor/resource-admission.js +23 -0
- package/dist/src/backends/harbor/resource-admission.js.map +1 -0
- package/dist/src/cli/commands/resources.js +23 -0
- package/dist/src/cli/commands/resources.js.map +1 -0
- package/dist/src/cli/main.js +2 -0
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/control-plane/remote-offer-contract.js +11 -2
- package/dist/src/control-plane/remote-offer-contract.js.map +1 -1
- package/dist/src/control-plane/remote-result-transport.js +10 -0
- package/dist/src/control-plane/remote-result-transport.js.map +1 -1
- package/dist/src/control-plane/remote-work-coordinator.js +4 -1
- package/dist/src/control-plane/remote-work-coordinator.js.map +1 -1
- package/dist/src/control-plane/remote-work-inputs.js +16 -4
- package/dist/src/control-plane/remote-work-inputs.js.map +1 -1
- package/dist/src/control-plane/remote-worker-client.js +22 -0
- package/dist/src/control-plane/remote-worker-client.js.map +1 -1
- package/dist/src/control-plane/remote-worker-codecs.js +1 -1
- package/dist/src/control-plane/remote-worker-codecs.js.map +1 -1
- package/dist/src/control-plane/remote-worker-protocol.js +12 -2
- package/dist/src/control-plane/remote-worker-protocol.js.map +1 -1
- package/dist/src/control-plane/remote-worker-runner.js +1 -1
- package/dist/src/control-plane/remote-worker-runner.js.map +1 -1
- package/dist/src/control-plane/remote-workers.js +2 -1
- package/dist/src/control-plane/remote-workers.js.map +1 -1
- package/dist/src/domain/validation.js +41 -6
- package/dist/src/domain/validation.js.map +1 -1
- package/dist/src/evals/benchmark-adapter-manifest.js +4 -0
- package/dist/src/evals/benchmark-adapter-manifest.js.map +1 -1
- package/dist/src/evals/benchmark-candidate.js +11 -3
- package/dist/src/evals/benchmark-candidate.js.map +1 -1
- package/dist/src/evals/eval-result-builder.js +22 -1
- package/dist/src/evals/eval-result-builder.js.map +1 -1
- package/dist/src/evals/index.js +1 -0
- package/dist/src/evals/index.js.map +1 -1
- package/dist/src/evals/planned-execution.js +5 -14
- package/dist/src/evals/planned-execution.js.map +1 -1
- package/dist/src/evals/request.js +9 -0
- package/dist/src/evals/request.js.map +1 -1
- package/dist/src/evals/resource-eval-lifecycle.js +31 -0
- package/dist/src/evals/resource-eval-lifecycle.js.map +1 -0
- package/dist/src/evals/resource-legacy-export.js +57 -0
- package/dist/src/evals/resource-legacy-export.js.map +1 -0
- package/dist/src/evals/service.js +5 -20
- package/dist/src/evals/service.js.map +1 -1
- package/dist/src/evals/task-resources.js +12 -4
- package/dist/src/evals/task-resources.js.map +1 -1
- package/dist/src/evals/trial-bundle-files.js +81 -0
- package/dist/src/evals/trial-bundle-files.js.map +1 -0
- package/dist/src/evals/trial-import.js +7 -78
- package/dist/src/evals/trial-import.js.map +1 -1
- package/dist/src/foundation/durable-json.js +33 -0
- package/dist/src/foundation/durable-json.js.map +1 -0
- package/dist/src/foundation/index.js +2 -0
- package/dist/src/foundation/index.js.map +1 -1
- package/dist/src/foundation/resource-image-references.js +52 -0
- package/dist/src/foundation/resource-image-references.js.map +1 -0
- package/dist/src/images/gc.js +2 -2
- package/dist/src/images/gc.js.map +1 -1
- package/dist/src/images/registry.js +27 -2
- package/dist/src/images/registry.js.map +1 -1
- package/dist/src/resources/api.js +207 -0
- package/dist/src/resources/api.js.map +1 -0
- package/dist/src/resources/bundle.js +117 -0
- package/dist/src/resources/bundle.js.map +1 -0
- package/dist/src/resources/evidence.js +93 -0
- package/dist/src/resources/evidence.js.map +1 -0
- package/dist/src/resources/gc.js +123 -0
- package/dist/src/resources/gc.js.map +1 -0
- package/dist/src/resources/index.js +14 -0
- package/dist/src/resources/index.js.map +1 -0
- package/dist/src/resources/materialize.js +143 -0
- package/dist/src/resources/materialize.js.map +1 -0
- package/dist/src/resources/object-store.js +191 -0
- package/dist/src/resources/object-store.js.map +1 -0
- package/dist/src/resources/oci-layer-validation.js +202 -0
- package/dist/src/resources/oci-layer-validation.js.map +1 -0
- package/dist/src/resources/oci-provider.js +101 -0
- package/dist/src/resources/oci-provider.js.map +1 -0
- package/dist/src/resources/oci-registry-bundle.js +253 -0
- package/dist/src/resources/oci-registry-bundle.js.map +1 -0
- package/dist/src/resources/protocol.js +222 -0
- package/dist/src/resources/protocol.js.map +1 -0
- package/dist/src/resources/result-retention.js +93 -0
- package/dist/src/resources/result-retention.js.map +1 -0
- package/dist/src/resources/role-context.js +54 -0
- package/dist/src/resources/role-context.js.map +1 -0
- package/dist/src/resources/stats.js +36 -0
- package/dist/src/resources/stats.js.map +1 -0
- package/dist/src/resources/store.js +310 -0
- package/dist/src/resources/store.js.map +1 -0
- package/dist/src/resources/tasks.js +153 -0
- package/dist/src/resources/tasks.js.map +1 -0
- package/dist/src/resources/transfer.js +162 -0
- package/dist/src/resources/transfer.js.map +1 -0
- package/dist/src/resources/views.js +130 -0
- package/dist/src/resources/views.js.map +1 -0
- package/dist/src/trajectories/analysis.js +31 -9
- package/dist/src/trajectories/analysis.js.map +1 -1
- package/dist/src/trajectories/chunk-projection.js +24 -11
- package/dist/src/trajectories/chunk-projection.js.map +1 -1
- package/dist/src/trajectories/contract.js +4 -0
- package/dist/src/trajectories/contract.js.map +1 -1
- package/dist/src/trajectories/dsh-chunk-contract.js +2 -2
- package/dist/src/trajectories/dsh-chunk-contract.js.map +1 -1
- package/dist/src/trajectories/dsh-contract.js +114 -17
- package/dist/src/trajectories/dsh-contract.js.map +1 -1
- package/dist/src/trajectories/embedded-stream.js +95 -0
- package/dist/src/trajectories/embedded-stream.js.map +1 -0
- package/dist/src/trajectories/events-chunk-drill.js +40 -0
- package/dist/src/trajectories/events-chunk-drill.js.map +1 -1
- package/dist/src/trajectories/events-page.js +43 -3
- package/dist/src/trajectories/events-page.js.map +1 -1
- package/dist/src/trajectories/format.js +3 -7
- package/dist/src/trajectories/format.js.map +1 -1
- package/dist/src/trajectories/index.js +1 -1
- package/dist/src/trajectories/index.js.map +1 -1
- package/dist/src/trajectories/providers/deepseek-codec.js +134 -0
- package/dist/src/trajectories/providers/deepseek-codec.js.map +1 -0
- package/dist/src/trajectories/providers/deepseek.js +32 -20
- package/dist/src/trajectories/providers/deepseek.js.map +1 -1
- package/dist/src/trajectories/request-attempt.js +16 -3
- package/dist/src/trajectories/request-attempt.js.map +1 -1
- package/dist/src/trajectories/store.js +28 -13
- package/dist/src/trajectories/store.js.map +1 -1
- package/dist/src/trajectories/stream-reader.js +12 -4
- package/dist/src/trajectories/stream-reader.js.map +1 -1
- package/dist/src/trajectories/surface-fold.js +26 -6
- package/dist/src/trajectories/surface-fold.js.map +1 -1
- package/dist/src/trajectories/unstarted-tool-repair.js +65 -0
- package/dist/src/trajectories/unstarted-tool-repair.js.map +1 -0
- package/dist/src/workers/remote-harbor-work-spec.js +9 -3
- package/dist/src/workers/remote-harbor-work-spec.js.map +1 -1
- package/dist/src/workers/remote-harbor-worker.js +24 -9
- package/dist/src/workers/remote-harbor-worker.js.map +1 -1
- package/docs/resource-storage.zh-CN.md +95 -0
- package/docs/schemas/execution-provider-status.schema.json +20 -0
- package/docs/schemas/hitch-resource-dataset-v2.schema.json +590 -0
- package/docs/schemas/hitch-resource-lock-v1.schema.json +341 -0
- package/docs/schemas/hitch-resource-plan-v1.schema.json +423 -0
- package/docs/schemas/hitch-resource-selection-v1.schema.json +608 -0
- package/docs/schemas/hitch-tree-v1.schema.json +75 -0
- package/docs/schemas/remote-harbor-work-spec.schema.json +47 -3
- package/docs/schemas/remote-work-offer.schema.json +2 -1
- package/docs/schemas/remote-worker-registration.schema.json +20 -0
- package/docs/schemas/trajectory-analysis.schema.json +17 -3
- package/package.json +9 -3
- package/test-contracts/hitch-resources-v1.json +197 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
|
+
import { lstat, mkdir, readFile, readdir, rm } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { durableWriteJSON as atomicWriteJSON, removeResourceImageFence, withEnvironmentImageReferenceLock, withFileLock, writeResourceImageFence } from "../foundation/index.js";
|
|
6
|
+
import { ObjectStore, limits } from "./object-store.js";
|
|
7
|
+
import { canonical, hash, identity, natural, object, parseResourceLock, parseStrictJson, sha } from "./protocol.js";
|
|
8
|
+
export class ResourceStore {
|
|
9
|
+
root;
|
|
10
|
+
options;
|
|
11
|
+
admissionImages = new AsyncLocalStorage();
|
|
12
|
+
objects;
|
|
13
|
+
directory;
|
|
14
|
+
constructor(root, options = {}) {
|
|
15
|
+
this.root = root;
|
|
16
|
+
this.options = options;
|
|
17
|
+
if (options.images && options.images.protocol !== "hitch-oci-provider@1")
|
|
18
|
+
throw new TypeError("unsupported OCI provider protocol");
|
|
19
|
+
this.objects = new ObjectStore(path.resolve(root), limits(options.limits));
|
|
20
|
+
this.directory = this.objects.directory;
|
|
21
|
+
}
|
|
22
|
+
admission(operation) { return this.admissionImages.run(new Map(), operation); }
|
|
23
|
+
async locked(operation, signal) {
|
|
24
|
+
await mkdir(this.directory, { recursive: true });
|
|
25
|
+
if (!(await lstat(this.directory)).isDirectory())
|
|
26
|
+
throw new Error("resource store must be a directory");
|
|
27
|
+
return withFileLock(path.join(this.root, "locks", "benchmark-resources"), "global", operation, { signal, timeoutCode: "resource_store_locked" });
|
|
28
|
+
}
|
|
29
|
+
async importImageArchive(lease, resource, source, signal) {
|
|
30
|
+
await this.locked(() => withEnvironmentImageReferenceLock(this.root, async () => {
|
|
31
|
+
if (!this.options.images?.importArchive)
|
|
32
|
+
throw new Error("OCI archive import unsupported");
|
|
33
|
+
await writeResourceImageFence(this.root, { protocol: "hitch-resource-image-fence@1", owner: `lease:${lease.id}`, state: "preparing", imageIds: lease.imageIds });
|
|
34
|
+
await this.options.images.importArchive(resource, source, signal, { maxExpandedBytes: this.objects.budget.maxTotalBytes, maxFiles: this.objects.budget.maxFiles });
|
|
35
|
+
const resolved = await this.options.images.resolve(resource, signal);
|
|
36
|
+
lease.imageIds = [...new Set([...lease.imageIds, resolved.imageId])].sort();
|
|
37
|
+
await atomicWriteJSON(this.recordPath("leases", lease.id), lease);
|
|
38
|
+
await writeResourceImageFence(this.root, { protocol: "hitch-resource-image-fence@1", owner: `lease:${lease.id}`, state: "active", imageIds: lease.imageIds });
|
|
39
|
+
}), signal);
|
|
40
|
+
}
|
|
41
|
+
recordPath(kind, key) { return path.join(this.directory, kind, `${hash(key).slice(7)}.json`); }
|
|
42
|
+
async readRecord(kind, key) {
|
|
43
|
+
try {
|
|
44
|
+
const file = this.recordPath(kind, key);
|
|
45
|
+
if (!(await lstat(file)).isFile())
|
|
46
|
+
throw new TypeError("resource record must be a regular file");
|
|
47
|
+
return parseStrictJson(await readFile(file, "utf8"));
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (error.code === "ENOENT")
|
|
51
|
+
return undefined;
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async records(kind) {
|
|
56
|
+
const dir = path.join(this.directory, kind);
|
|
57
|
+
const files = await readdir(dir).catch((e) => { if (e.code !== "ENOENT")
|
|
58
|
+
throw e; return []; });
|
|
59
|
+
return Promise.all(files.map(async (file) => {
|
|
60
|
+
if (!/^[a-f0-9]{64}\.json$/.test(file) || !(await lstat(path.join(dir, file))).isFile())
|
|
61
|
+
throw new TypeError("invalid resource record filename");
|
|
62
|
+
const value = parseStrictJson(await readFile(path.join(dir, file), "utf8"));
|
|
63
|
+
const key = kind === "roots" ? value.owner : value.id;
|
|
64
|
+
if (typeof key !== "string" || file !== `${hash(key).slice(7)}.json`)
|
|
65
|
+
throw new TypeError("resource record address mismatch");
|
|
66
|
+
return value;
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
async beginLease(owner, purpose) {
|
|
70
|
+
validateOwner(owner);
|
|
71
|
+
const lease = { protocol: "hitch-resource-lease@1", id: randomUUID(), owner, purpose, state: "active", objectDigests: [], imageIds: [], createdAt: new Date().toISOString() };
|
|
72
|
+
await atomicWriteJSON(this.recordPath("leases", lease.id), lease);
|
|
73
|
+
return lease;
|
|
74
|
+
}
|
|
75
|
+
async protect(lease, digest) {
|
|
76
|
+
if (!lease.objectDigests.includes(digest)) {
|
|
77
|
+
lease.objectDigests.push(digest);
|
|
78
|
+
lease.objectDigests.sort();
|
|
79
|
+
await atomicWriteJSON(this.recordPath("leases", lease.id), lease);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async import(source, kind, owner, signal) {
|
|
83
|
+
return this.locked(async () => {
|
|
84
|
+
const lease = await this.beginLease(owner, "import"), staging = path.join(this.directory, "staging", lease.id);
|
|
85
|
+
await atomicWriteJSON(this.recordPath("transactions", lease.id), { protocol: "hitch-resource-transaction@1", id: lease.id, owner, state: "importing" });
|
|
86
|
+
await mkdir(staging, { recursive: true });
|
|
87
|
+
try {
|
|
88
|
+
const result = kind === "blob" ? await this.objects.importFile(source, staging, d => this.protect(lease, d), signal)
|
|
89
|
+
: await this.objects.importTree(source, staging, d => this.protect(lease, d), signal);
|
|
90
|
+
await atomicWriteJSON(this.recordPath("transactions", lease.id), { protocol: "hitch-resource-transaction@1", id: lease.id, owner, state: "imported", resource: result.resource });
|
|
91
|
+
return { ...result, leaseId: lease.id, logicalBytes: "logicalBytes" in result ? result.logicalBytes : result.resource.size };
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
lease.state = "released";
|
|
95
|
+
await atomicWriteJSON(this.recordPath("leases", lease.id), lease);
|
|
96
|
+
await atomicWriteJSON(this.recordPath("transactions", lease.id), { protocol: "hitch-resource-transaction@1", id: lease.id, owner, state: "failed" });
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
await rm(staging, { recursive: true, force: true });
|
|
101
|
+
}
|
|
102
|
+
}, signal);
|
|
103
|
+
}
|
|
104
|
+
/** Caller holds the store lock; no content trust is cached across admissions. */
|
|
105
|
+
async closure(lock, lease, signal) {
|
|
106
|
+
const parsed = parseResourceLock(lock), objectDigests = new Set(), images = [];
|
|
107
|
+
let logicalBytes = 0, files = 0;
|
|
108
|
+
for (const resource of Object.values(parsed.resources)) {
|
|
109
|
+
signal?.throwIfAborted();
|
|
110
|
+
if (resource.kind === "oci-image")
|
|
111
|
+
continue;
|
|
112
|
+
const digest = resource.kind === "blob" ? resource.digest : resource.manifestDigest;
|
|
113
|
+
await this.protect(lease, digest);
|
|
114
|
+
await restoreObject(this, digest);
|
|
115
|
+
await this.objects.verify(digest, resource.kind === "blob" ? resource.size : undefined);
|
|
116
|
+
objectDigests.add(digest);
|
|
117
|
+
if (resource.kind === "blob") {
|
|
118
|
+
logicalBytes += resource.size;
|
|
119
|
+
files++;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const tree = await this.objects.readTree(digest);
|
|
123
|
+
files += tree.entries.length;
|
|
124
|
+
for (const entry of tree.entries)
|
|
125
|
+
if (entry.kind === "file") {
|
|
126
|
+
await this.protect(lease, entry.digest);
|
|
127
|
+
await restoreObject(this, entry.digest);
|
|
128
|
+
await this.objects.verify(entry.digest, entry.size);
|
|
129
|
+
objectDigests.add(entry.digest);
|
|
130
|
+
logicalBytes += entry.size;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (logicalBytes > this.objects.budget.maxTotalBytes || files > this.objects.budget.maxFiles)
|
|
134
|
+
throw new Error("resource closure budget exceeded");
|
|
135
|
+
}
|
|
136
|
+
const oci = Object.entries(parsed.resources).filter((entry) => entry[1].kind === "oci-image");
|
|
137
|
+
if (oci.length) {
|
|
138
|
+
if (!this.options.images)
|
|
139
|
+
throw new Error("OCI resource provider unavailable");
|
|
140
|
+
await withEnvironmentImageReferenceLock(this.root, async () => {
|
|
141
|
+
await writeResourceImageFence(this.root, { protocol: "hitch-resource-image-fence@1", owner: `lease:${lease.id}`, state: "preparing", imageIds: lease.imageIds });
|
|
142
|
+
const resolved = this.admissionImages.getStore() ?? new Map();
|
|
143
|
+
for (const [id, resource] of oci) {
|
|
144
|
+
const key = canonical(resource), value = resolved.get(key) ?? await this.options.images.resolve(resource, signal);
|
|
145
|
+
resolved.set(key, value);
|
|
146
|
+
if (sha(value.manifestDigest) !== resource.manifestDigest || value.platform !== resource.platform || !value.reference.endsWith(`@${resource.manifestDigest}`))
|
|
147
|
+
throw new Error("OCI resource identity mismatch");
|
|
148
|
+
sha(value.configDigest);
|
|
149
|
+
sha(value.imageId);
|
|
150
|
+
images.push({ resource: id, ...value });
|
|
151
|
+
}
|
|
152
|
+
lease.imageIds = [...new Set(images.map(i => i.imageId))].sort();
|
|
153
|
+
await atomicWriteJSON(this.recordPath("leases", lease.id), lease);
|
|
154
|
+
await writeResourceImageFence(this.root, { protocol: "hitch-resource-image-fence@1", owner: `lease:${lease.id}`, state: "active", imageIds: lease.imageIds });
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const content = { protocol: "hitch-resource-closure@1", resources: parsed.resources, objectDigests: [...objectDigests].sort() };
|
|
158
|
+
// Locations and local provider IDs are evidence, not closure identity.
|
|
159
|
+
return { ...content, images, logicalBytes, digest: identity(content.protocol, content) };
|
|
160
|
+
}
|
|
161
|
+
async acquire(owner, lock, purpose = "preflight", signal) {
|
|
162
|
+
const parsed = parseResourceLock(lock);
|
|
163
|
+
return this.locked(async () => { const lease = await this.beginLease(owner, purpose); return { lease, closure: await this.closure(parsed, lease, signal) }; }, signal);
|
|
164
|
+
}
|
|
165
|
+
async pin(input, signal) {
|
|
166
|
+
validateOwner(input.owner);
|
|
167
|
+
generation(input.generation);
|
|
168
|
+
validateOwner(input.purpose);
|
|
169
|
+
const lock = parseResourceLock(input.lock);
|
|
170
|
+
return this.locked(async () => {
|
|
171
|
+
const previous = await this.readRecord("roots", input.owner);
|
|
172
|
+
if (previous) {
|
|
173
|
+
validateRoot(previous);
|
|
174
|
+
if (previous.owner !== input.owner)
|
|
175
|
+
throw new Error("resource owner address mismatch");
|
|
176
|
+
if (previous.generation > input.generation || previous.generation === input.generation && previous.state === "released")
|
|
177
|
+
throw new Error("resource owner generation has been released or superseded");
|
|
178
|
+
if (previous.state === "active" && (previous.generation !== input.generation || canonical(previous.lock) !== canonical(lock) || previous.purpose !== input.purpose))
|
|
179
|
+
throw new Error("active owner generation cannot be replaced");
|
|
180
|
+
}
|
|
181
|
+
const lease = await this.beginLease(input.owner, "preflight"), closure = await this.closure(lock, lease, signal);
|
|
182
|
+
const record = { protocol: "hitch-resource-root@1", owner: input.owner, generation: input.generation, purpose: input.purpose, state: "active", lock, closure };
|
|
183
|
+
await withEnvironmentImageReferenceLock(this.root, async () => {
|
|
184
|
+
await writeResourceImageFence(this.root, { protocol: "hitch-resource-image-fence@1", owner: `root:${input.owner}:${input.generation}`, state: "active", imageIds: lease.imageIds });
|
|
185
|
+
await atomicWriteJSON(this.recordPath("roots", input.owner), record);
|
|
186
|
+
});
|
|
187
|
+
await this.finishLeaseLocked(lease);
|
|
188
|
+
return record;
|
|
189
|
+
}, signal);
|
|
190
|
+
}
|
|
191
|
+
async release(owner, expectedGeneration) {
|
|
192
|
+
validateOwner(owner);
|
|
193
|
+
generation(expectedGeneration);
|
|
194
|
+
await this.locked(async () => {
|
|
195
|
+
const record = await this.readRecord("roots", owner);
|
|
196
|
+
if (!record)
|
|
197
|
+
throw new Error("resource owner is missing");
|
|
198
|
+
validateRoot(record);
|
|
199
|
+
if (record.owner !== owner)
|
|
200
|
+
throw new Error("resource owner address mismatch");
|
|
201
|
+
if (record.generation !== expectedGeneration)
|
|
202
|
+
throw new Error("stale resource owner generation");
|
|
203
|
+
// Persist tombstone first. An interrupted release may retain an extra image fence.
|
|
204
|
+
record.state = "released";
|
|
205
|
+
await atomicWriteJSON(this.recordPath("roots", owner), record);
|
|
206
|
+
await withEnvironmentImageReferenceLock(this.root, () => removeResourceImageFence(this.root, `root:${owner}:${expectedGeneration}`));
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
async finishLease(id, confirmation) {
|
|
210
|
+
if (!["ended", "unknown"].includes(confirmation))
|
|
211
|
+
throw new TypeError("explicit lease end or unknown confirmation required");
|
|
212
|
+
await this.locked(async () => {
|
|
213
|
+
const lease = await this.readRecord("leases", id);
|
|
214
|
+
if (!lease)
|
|
215
|
+
throw new Error("resource lease missing");
|
|
216
|
+
validateLease(lease);
|
|
217
|
+
if (lease.id !== id)
|
|
218
|
+
throw new Error("resource lease address mismatch");
|
|
219
|
+
if (confirmation === "unknown") {
|
|
220
|
+
if (lease.state !== "released") {
|
|
221
|
+
lease.state = "unknown";
|
|
222
|
+
await atomicWriteJSON(this.recordPath("leases", id), lease);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
// The same lock excludes a live importer. Only its UUID staging is
|
|
227
|
+
// owned here; unfamiliar directories and execution workspaces remain.
|
|
228
|
+
if (lease.purpose === "import") {
|
|
229
|
+
const staging = path.join(this.directory, "staging", id);
|
|
230
|
+
const info = await lstat(staging).catch(e => { if (e.code !== "ENOENT")
|
|
231
|
+
throw e; return undefined; });
|
|
232
|
+
if (info && !info.isDirectory())
|
|
233
|
+
throw new Error("unsafe import staging ownership");
|
|
234
|
+
await rm(staging, { recursive: true, force: true });
|
|
235
|
+
const transaction = await this.readRecord("transactions", id);
|
|
236
|
+
if (transaction) {
|
|
237
|
+
if (transaction.protocol !== "hitch-resource-transaction@1" || transaction.id !== id || transaction.owner !== lease.owner)
|
|
238
|
+
throw new Error("import transaction ownership mismatch");
|
|
239
|
+
await atomicWriteJSON(this.recordPath("transactions", id), { ...transaction, state: "ended" });
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
await this.finishLeaseLocked(lease);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
async finishLeaseLocked(lease) {
|
|
247
|
+
lease.state = "released";
|
|
248
|
+
await atomicWriteJSON(this.recordPath("leases", lease.id), lease);
|
|
249
|
+
await withEnvironmentImageReferenceLock(this.root, () => removeResourceImageFence(this.root, `lease:${lease.id}`));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
export function validateOwner(value) {
|
|
253
|
+
if (typeof value !== "string" || !value || value.length > 512 || /[\x00-\x1f]/.test(value))
|
|
254
|
+
throw new TypeError("invalid resource owner or purpose");
|
|
255
|
+
}
|
|
256
|
+
function generation(value) { if (natural(value) < 1)
|
|
257
|
+
throw new TypeError("resource generation must be positive"); }
|
|
258
|
+
export function validateLease(value) {
|
|
259
|
+
object(value, ["protocol", "id", "owner", "purpose", "state", "objectDigests", "imageIds", "createdAt"]);
|
|
260
|
+
if (value.protocol !== "hitch-resource-lease@1" || !/^[0-9a-f-]{36}$/.test(value.id) || !["import", "preflight", "execution", "export"].includes(value.purpose) || !["active", "unknown", "released"].includes(value.state) || !Number.isFinite(Date.parse(value.createdAt)))
|
|
261
|
+
throw new TypeError("invalid resource lease");
|
|
262
|
+
validateOwner(value.owner);
|
|
263
|
+
if (!Array.isArray(value.objectDigests) || !Array.isArray(value.imageIds))
|
|
264
|
+
throw new TypeError("invalid lease closure");
|
|
265
|
+
value.objectDigests.forEach(sha);
|
|
266
|
+
value.imageIds.forEach(sha);
|
|
267
|
+
}
|
|
268
|
+
export function validateRoot(value) {
|
|
269
|
+
object(value, ["protocol", "owner", "generation", "purpose", "state", "lock", "closure"]);
|
|
270
|
+
if (value.protocol !== "hitch-resource-root@1" || !["active", "released"].includes(value.state))
|
|
271
|
+
throw new TypeError("invalid resource root");
|
|
272
|
+
validateOwner(value.owner);
|
|
273
|
+
validateOwner(value.purpose);
|
|
274
|
+
generation(value.generation);
|
|
275
|
+
parseResourceLock(value.lock);
|
|
276
|
+
const c = value.closure;
|
|
277
|
+
object(c, ["protocol", "resources", "objectDigests", "images", "digest", "logicalBytes"]);
|
|
278
|
+
if (c.protocol !== "hitch-resource-closure@1" || canonical(c.resources) !== canonical(value.lock.resources) || !Array.isArray(c.objectDigests) || !Array.isArray(c.images)
|
|
279
|
+
|| identity(c.protocol, { protocol: c.protocol, resources: c.resources, objectDigests: c.objectDigests }) !== c.digest)
|
|
280
|
+
throw new TypeError("invalid root closure");
|
|
281
|
+
c.objectDigests.forEach(sha);
|
|
282
|
+
natural(c.logicalBytes);
|
|
283
|
+
const expected = Object.entries(value.lock.resources).filter(([, r]) => r.kind === "oci-image").map(([id]) => id).sort();
|
|
284
|
+
if (canonical(c.images.map(i => i.resource).sort()) !== canonical(expected))
|
|
285
|
+
throw new TypeError("root OCI closure is incomplete");
|
|
286
|
+
for (const image of c.images) {
|
|
287
|
+
object(image, ["resource", "imageId", "configDigest", "manifestDigest", "platform", "reference"]);
|
|
288
|
+
const resource = value.lock.resources[image.resource];
|
|
289
|
+
if (resource?.kind !== "oci-image" || image.manifestDigest !== resource.manifestDigest || image.platform !== resource.platform || typeof image.reference !== "string" || !image.reference.endsWith(`@${resource.manifestDigest}`))
|
|
290
|
+
throw new TypeError("invalid root OCI identity");
|
|
291
|
+
sha(image.imageId);
|
|
292
|
+
sha(image.configDigest);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
export async function restoreObject(store, digest) {
|
|
296
|
+
const { rename } = await import("node:fs/promises");
|
|
297
|
+
const objectFile = store.objects.objectPath(digest), quarantined = path.join(store.directory, "quarantine", digest.slice(7));
|
|
298
|
+
try {
|
|
299
|
+
await lstat(objectFile);
|
|
300
|
+
}
|
|
301
|
+
catch (e) {
|
|
302
|
+
if (e.code !== "ENOENT")
|
|
303
|
+
throw e;
|
|
304
|
+
await mkdir(path.dirname(objectFile), { recursive: true });
|
|
305
|
+
await store.objects.verify(digest, undefined, quarantined);
|
|
306
|
+
await rename(quarantined, objectFile); // Missing content fails; never pins a dangling ref.
|
|
307
|
+
await rm(path.join(store.directory, "quarantine-index", `${digest.slice(7)}.json`), { force: true });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/resources/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { resourceDescriptorDirectory } from "./views.js";
|
|
2
|
+
import { validateRoleContexts } from "./role-context.js";
|
|
3
|
+
import { lstat, readFile } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { canonical, identity, object, parseResourceLock, parseStrictJson, portablePath, resourceId, sha } from "./protocol.js";
|
|
6
|
+
export const RESOURCE_EXECUTION_CAPABILITIES = ["blob@1", "tree@1", "oci-image@1", "input-file@1", "input-tree@1", "environment-image@1", "private-copy@1", "harbor-role-context@1"];
|
|
7
|
+
export function parseResourceTask(value) {
|
|
8
|
+
const raw = object(value, ["task_id", "source_task_digest", "resource_closure_digest", "task_digest", "sourceTree", "lock"]);
|
|
9
|
+
const tree = object(raw.sourceTree, ["kind", "format", "manifestDigest"]);
|
|
10
|
+
if (tree.kind !== "tree" || tree.format !== "hitch-tree@1")
|
|
11
|
+
throw new TypeError("task source must be a versioned tree");
|
|
12
|
+
const sourceTree = { kind: "tree", format: "hitch-tree@1", manifestDigest: sha(tree.manifestDigest) };
|
|
13
|
+
const source = identity("hitch-source-task@1", sourceTree);
|
|
14
|
+
if (sha(raw.source_task_digest) !== source)
|
|
15
|
+
throw new TypeError("source task identity mismatch");
|
|
16
|
+
const resource_closure_digest = sha(raw.resource_closure_digest), task_digest = identity("hitch-task@2", { source_task_digest: source, resource_closure_digest });
|
|
17
|
+
if (sha(raw.task_digest) !== task_digest)
|
|
18
|
+
throw new TypeError("resource task identity mismatch");
|
|
19
|
+
return { task_id: portablePath(resourceId(raw.task_id)), sourceTree, source_task_digest: source, resource_closure_digest, task_digest, lock: parseResourceLock(raw.lock) };
|
|
20
|
+
}
|
|
21
|
+
export function parseResourceDataset(value) {
|
|
22
|
+
const raw = object(value, ["schema_version", "kind", "resource_protocol", "execution", "required_capabilities", "benchmark", "adapter", "scoring", "raw_metrics", "tasks", "dataset_digest"]);
|
|
23
|
+
if (raw.schema_version !== "2" || raw.kind !== "gear-harbor-benchmark" || raw.resource_protocol !== "hitch-resource-lock@1")
|
|
24
|
+
throw new TypeError("unsupported resource dataset");
|
|
25
|
+
const execution = object(raw.execution, ["backend", "resolver", "platform"]);
|
|
26
|
+
if (execution.backend !== "harbor-role-context@1" || execution.resolver !== "hitch-resource-resolver@1" || typeof execution.platform !== "string" || !/^linux\/(amd64|arm64)(\/v[0-9]+)?$/.test(execution.platform))
|
|
27
|
+
throw new TypeError("unsupported resource execution contract");
|
|
28
|
+
const benchmark = object(raw.benchmark, ["id", "revision"]), adapter = object(raw.adapter, ["id", "revision", "output_protocol"]);
|
|
29
|
+
for (const item of [benchmark, adapter])
|
|
30
|
+
if (typeof item.id !== "string" || !item.id || typeof item.revision !== "string" || !item.revision || item.revision === "latest")
|
|
31
|
+
throw new TypeError("invalid benchmark/adapter identity");
|
|
32
|
+
if (adapter.output_protocol !== "gear-harbor-eval-result-v1" || !Array.isArray(raw.tasks) || !raw.tasks.length)
|
|
33
|
+
throw new TypeError("invalid resource dataset tasks or adapter");
|
|
34
|
+
const scoring = object(raw.scoring, ["total_score", "process_score"]);
|
|
35
|
+
for (const key of ["total_score", ...(scoring.process_score === undefined ? [] : ["process_score"])]) {
|
|
36
|
+
const score = object(scoring[key], ["source_metric", "direction", "range", "reducer"]);
|
|
37
|
+
if (typeof score.source_metric !== "string" || !score.source_metric || !["maximize", "minimize"].includes(String(score.direction)) || score.reducer !== "task-macro-mean"
|
|
38
|
+
|| !Array.isArray(score.range) || score.range.length !== 2 || !score.range.every(Number.isFinite) || score.range[0] >= score.range[1])
|
|
39
|
+
throw new TypeError("invalid resource scoring contract");
|
|
40
|
+
}
|
|
41
|
+
if (!Array.isArray(raw.required_capabilities) || raw.required_capabilities.some(c => typeof c !== "string") || new Set(raw.required_capabilities).size !== raw.required_capabilities.length)
|
|
42
|
+
throw new TypeError("invalid resource dataset capabilities");
|
|
43
|
+
if (raw.raw_metrics !== undefined) {
|
|
44
|
+
const registry = object(raw.raw_metrics, ["schema_version", "metrics"]);
|
|
45
|
+
if (registry.schema_version !== "1" || !Array.isArray(registry.metrics))
|
|
46
|
+
throw new TypeError("invalid raw metric registry");
|
|
47
|
+
}
|
|
48
|
+
const tasks = raw.tasks.map(parseResourceTask), ids = tasks.map(t => t.task_id);
|
|
49
|
+
if (new Set(ids.map(id => id.toLowerCase())).size !== ids.length || canonical(ids) !== canonical([...ids].sort()))
|
|
50
|
+
throw new TypeError("resource dataset tasks must be sorted and unique");
|
|
51
|
+
const { dataset_digest, ...body } = raw;
|
|
52
|
+
if (sha(dataset_digest) !== identity("hitch-resource-dataset@2", body))
|
|
53
|
+
throw new TypeError("resource dataset digest mismatch");
|
|
54
|
+
return { ...raw, tasks };
|
|
55
|
+
}
|
|
56
|
+
export function selectResources(dataset, ids) {
|
|
57
|
+
const sorted = [...ids].sort();
|
|
58
|
+
if (!sorted.length || new Set(ids.map(id => id.toLowerCase())).size !== ids.length || sorted.some(id => !dataset.tasks.some(t => t.task_id === id)))
|
|
59
|
+
throw new TypeError("invalid resource selection");
|
|
60
|
+
const { tasks, dataset_digest, ...manifest } = dataset;
|
|
61
|
+
const body = { protocol: "hitch-resource-selection@1", sourceDatasetDigest: dataset_digest, manifest, tasks: tasks.filter(t => sorted.includes(t.task_id)) };
|
|
62
|
+
return { ...body, digest: identity(body.protocol, body) };
|
|
63
|
+
}
|
|
64
|
+
export function parseResourceSelection(value) {
|
|
65
|
+
const raw = object(value, ["protocol", "sourceDatasetDigest", "manifest", "tasks", "digest"]);
|
|
66
|
+
if (raw.protocol !== "hitch-resource-selection@1")
|
|
67
|
+
throw new TypeError("unsupported resource selection");
|
|
68
|
+
const { digest, ...body } = raw;
|
|
69
|
+
if (sha(digest) !== identity(raw.protocol, body))
|
|
70
|
+
throw new TypeError("resource selection digest mismatch");
|
|
71
|
+
sha(raw.sourceDatasetDigest);
|
|
72
|
+
const manifest = object(raw.manifest, ["schema_version", "kind", "resource_protocol", "execution", "required_capabilities", "benchmark", "adapter", "scoring", "raw_metrics"]);
|
|
73
|
+
const datasetBody = { ...manifest, tasks: raw.tasks };
|
|
74
|
+
const dataset = parseResourceDataset({ ...datasetBody, dataset_digest: identity("hitch-resource-dataset@2", datasetBody) });
|
|
75
|
+
return { ...raw, tasks: dataset.tasks };
|
|
76
|
+
}
|
|
77
|
+
export async function readResourceInput(input) {
|
|
78
|
+
const info = await lstat(input).catch((e) => { if (e.code !== "ENOENT")
|
|
79
|
+
throw e; return undefined; });
|
|
80
|
+
if (!info)
|
|
81
|
+
return undefined;
|
|
82
|
+
if (info.isFile()) {
|
|
83
|
+
if (info.size > 16 * 1024 ** 2)
|
|
84
|
+
throw new Error("resource selection size limit exceeded");
|
|
85
|
+
return parseResourceSelection(parseStrictJson(await readFile(input, "utf8")));
|
|
86
|
+
}
|
|
87
|
+
if (!info.isDirectory())
|
|
88
|
+
throw new TypeError("resource input must be a regular file or directory");
|
|
89
|
+
try {
|
|
90
|
+
const file = path.join(input, "benchmark.adapter.json"), metadata = await lstat(file);
|
|
91
|
+
if (!metadata.isFile() || metadata.size > 16 * 1024 ** 2)
|
|
92
|
+
throw new Error("resource manifest must be a bounded regular file");
|
|
93
|
+
const text = await readFile(file, "utf8"), raw = parseStrictJson(text);
|
|
94
|
+
return raw.schema_version === "2" ? parseResourceDataset(raw) : undefined;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error.code === "ENOENT")
|
|
98
|
+
return undefined;
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export async function sealResourceTask(store, directory, taskId, owner, signal) {
|
|
103
|
+
const lock = parseResourceLock(parseStrictJson(await readFile(path.join(directory, "resource.lock.json"), "utf8")));
|
|
104
|
+
const source = await store.import(directory, "tree", `${owner}:source`, signal);
|
|
105
|
+
if (source.resource.kind !== "tree")
|
|
106
|
+
throw new Error("invalid source import");
|
|
107
|
+
const acquired = await store.acquire(owner, lock, "preflight", signal);
|
|
108
|
+
const source_task_digest = identity("hitch-source-task@1", source.resource), resource_closure_digest = acquired.closure.digest;
|
|
109
|
+
const task = { task_id: resourceId(taskId), sourceTree: source.resource, lock, source_task_digest, resource_closure_digest,
|
|
110
|
+
task_digest: identity("hitch-task@2", { source_task_digest, resource_closure_digest }) };
|
|
111
|
+
// The producer's stable durable pin retains both source and runtime inputs.
|
|
112
|
+
await store.pin({ owner, generation: 1, purpose: "dataset-task", lock: taskClosureLock(task) }, signal);
|
|
113
|
+
await store.finishLease(source.leaseId, "ended");
|
|
114
|
+
await store.finishLease(acquired.lease.id, "ended");
|
|
115
|
+
return task;
|
|
116
|
+
}
|
|
117
|
+
export function taskClosureLock(task) {
|
|
118
|
+
if ("hitch-task-source" in task.lock.resources)
|
|
119
|
+
throw new TypeError("reserved resource ID hitch-task-source");
|
|
120
|
+
return { ...task.lock, resources: { ...task.lock.resources, "hitch-task-source": task.sourceTree } };
|
|
121
|
+
}
|
|
122
|
+
export async function preflightResourceTask(store, task, input) {
|
|
123
|
+
task = parseResourceTask(task);
|
|
124
|
+
for (const capability of task.lock.requiredCapabilities)
|
|
125
|
+
if (!RESOURCE_EXECUTION_CAPABILITIES.includes(capability))
|
|
126
|
+
throw new Error(`unsupported required resource capability: ${capability}`);
|
|
127
|
+
for (const binding of task.lock.bindings)
|
|
128
|
+
if (binding.use !== "environment-image" && binding.access === "read-only")
|
|
129
|
+
throw new Error("Harbor role-context backend cannot enforce read-only input bindings");
|
|
130
|
+
for (const resource of Object.values(task.lock.resources))
|
|
131
|
+
if (resource.kind === "oci-image" && resource.platform !== input.platform)
|
|
132
|
+
throw new Error("resource platform mismatch");
|
|
133
|
+
const root = await store.pin({ owner: input.owner, generation: input.generation, purpose: "frozen-task", lock: taskClosureLock(task) }, input.signal);
|
|
134
|
+
const runtime = await store.acquire(`${input.owner}:verification`, task.lock, "preflight", input.signal);
|
|
135
|
+
if (runtime.closure.digest !== task.resource_closure_digest)
|
|
136
|
+
throw new Error("resource runtime closure changed");
|
|
137
|
+
await store.finishLease(runtime.lease.id, "ended");
|
|
138
|
+
const tree = await store.objects.readTree(task.sourceTree.manifestDigest), entry = tree.entries.find(e => e.path === "resource.lock.json");
|
|
139
|
+
if (entry?.kind !== "file" || canonical(parseResourceLock(parseStrictJson(await readFile(store.objects.objectPath(entry.digest), "utf8")))) !== canonical(task.lock))
|
|
140
|
+
throw new Error("task lock does not match its sealed source tree");
|
|
141
|
+
await validateRoleContexts(await resourceDescriptorDirectory(store, task), task.lock.bindings, input.platform, root.closure.images);
|
|
142
|
+
for (const binding of task.lock.bindings)
|
|
143
|
+
if (binding.use !== "environment-image") {
|
|
144
|
+
const role = binding.consumer.role === "candidate" ? "environment/candidate" : binding.consumer.role === "verifier" ? "tests" : `environment/services/${binding.consumer.serviceId}`;
|
|
145
|
+
const target = `${role}/${binding.target}`.toLowerCase();
|
|
146
|
+
if (tree.entries.some(e => e.path.toLowerCase() === target || e.path.toLowerCase().startsWith(`${target}/`) || e.kind === "file" && target.startsWith(`${e.path.toLowerCase()}/`)))
|
|
147
|
+
throw new Error("resource target collides with source descriptor");
|
|
148
|
+
}
|
|
149
|
+
const body = { protocol: "hitch-resource-plan@1", resolver: "hitch-resource-resolver@1", backend: "harbor-role-context@1", platform: input.platform, task };
|
|
150
|
+
return { plan: { ...body, digest: identity(body.protocol, body) }, closure: root.closure };
|
|
151
|
+
}
|
|
152
|
+
export { resourceDescriptorDirectory } from "./views.js";
|
|
153
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/resources/tasks.ts"],"names":[],"mappings":"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"}
|