@openpond/evals 0.2.0 → 0.4.0
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/CONTRACT.md +24 -5
- package/README.md +27 -8
- package/RELEASING.md +13 -45
- package/dist/compatibility.js +45 -0
- package/dist/conformance.js +7 -11
- package/dist/evidence/authoring.js +1 -1
- package/dist/evidence/conformance.js +1 -1
- package/dist/evidence/contracts.js +1 -2
- package/dist/evidence/eligibility.js +1 -1
- package/dist/graders.js +1 -1
- package/dist/harness.js +33 -103
- package/dist/index.js +3 -1
- package/dist/model-improvement-qualification.js +125 -0
- package/dist/review-conformance.js +209 -0
- package/dist/runs.js +33 -13
- package/dist/tasksets.js +3 -17
- package/dist/types/compatibility.d.ts +11 -0
- package/dist/types/compatibility.d.ts.map +1 -0
- package/dist/types/conformance.d.ts +10 -48
- package/dist/types/conformance.d.ts.map +1 -1
- package/dist/types/evidence/conformance.d.ts +8 -8
- package/dist/types/evidence/contracts.d.ts +8 -8
- package/dist/types/harness.d.ts +3 -471
- package/dist/types/harness.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/model-improvement-qualification.d.ts +222 -0
- package/dist/types/model-improvement-qualification.d.ts.map +1 -0
- package/dist/types/review-conformance.d.ts +607 -0
- package/dist/types/review-conformance.d.ts.map +1 -0
- package/dist/types/runs.d.ts +47 -10
- package/dist/types/runs.d.ts.map +1 -1
- package/dist/types/tasksets.d.ts +4 -35
- package/dist/types/tasksets.d.ts.map +1 -1
- package/package.json +14 -2
- package/dist/common.js +0 -67
- package/dist/sha256.js +0 -91
- package/dist/types/common.d.ts +0 -51
- package/dist/types/common.d.ts.map +0 -1
- package/dist/types/sha256.d.ts +0 -2
- package/dist/types/sha256.d.ts.map +0 -1
package/CONTRACT.md
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
# Portable contract map
|
|
2
2
|
|
|
3
|
-
`@openpond/
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
`@openpond/harness` owns immutable Harness identities, workspaces,
|
|
4
|
+
model-driven refinement/review policy, improvements, traces, tools, model
|
|
5
|
+
identities, and shared hashing.
|
|
6
|
+
`@openpond/evals` owns Tasksets, graders, evaluation runs and receipts,
|
|
7
|
+
execution orchestration, conformance fixtures, and Work-evidence eligibility.
|
|
8
|
+
Evals depends on Harness for exact release identities but does not re-export
|
|
9
|
+
Harness APIs; Harness never depends on Evals. Host applications own persistence, provider sessions, secret
|
|
10
|
+
leases, connected-app authorization, model streaming, artifact bytes, and
|
|
11
|
+
runtime processes.
|
|
6
12
|
|
|
7
13
|
| Existing object | Portable object | Migration rule |
|
|
8
14
|
| --- | --- | --- |
|
|
9
|
-
| `Taskset` | `TasksetRelease` | Project only the released tasks, policy, environment, tools, capabilities, graders
|
|
15
|
+
| `Taskset` | `TasksetRelease` | Project only the released tasks, policy, environment, tools, capabilities, and graders. A Taskset is deliberately independent of any Harness so the same workload can run against local or hosted execution. Authoring state and UI readiness remain host state. |
|
|
10
16
|
| `HarnessRunManifest` (`openpond.harnessRunManifest.v1`) | `RunManifest` (`openpond.runManifest.v1`) | Treat the old object as a legacy training projection. Normalize its release/model/runtime identities into one new manifest; recipe, compute, engine, secret leases, and approval records remain host bindings referenced by hashes. |
|
|
11
17
|
| `HarnessRunTrace` | `HarnessTrace` | Preserve ordered actions, observations, lifecycle events, terminal state, failure class, and trace hash. Learning-signal envelopes remain a training projection of the trace and receipt. |
|
|
12
18
|
| `TaskAttemptResult` | `AttemptReceipt` | Preserve the old record for application persistence while adding a lossless receipt reference. Output becomes `outputHash`; trace and artifacts are separately hash-bound. |
|
|
13
19
|
| `GradeResult` | `GraderEvidence[]` | Preserve component score, pass, reward eligibility, failure class, feedback, and visible/private evidence references. Aggregate UI results remain host projections. |
|
|
14
20
|
| managed-RL local receipt | `AttemptReceipt` | Submit canonical manifest/task/trace/artifact/grader identities; policy token responses and provider request IDs remain host-private trace data. |
|
|
15
|
-
| resolved training bundle | `HarnessRelease` + host training binding |
|
|
21
|
+
| resolved training bundle | `HarnessRelease` + host training binding | Agent snapshot, program, lifecycle, tool declarations, files, and grader interface belong to the Harness. Taskset environment/policy/graders and dataset/evidence, recipe, compute, engine, approval, and opaque leases remain explicit host-side bindings. |
|
|
16
22
|
| completed Work or Development turn | `WorkEvidenceReceipt` | Project the authoritative terminal turn, immutable Agent snapshot when available, model/runtime identity, sanitized trace reference, exact output revisions, validation evidence, interventions, timing, usage, and explicit consent provenance. Keep the raw source and trace host-private. |
|
|
17
23
|
| Agent plus environment runtime events | `WorkProcessTrace` | Emit one ordered trace with `agent` and `environment` layers. Bind every environment step to its outer Agent tool call or stable Agent-turn receipt hash. Hash inputs/outputs and expose only enumerated, bounded attributes. |
|
|
18
24
|
| user feedback on Work output | `WorkFeedbackReceipt` | Append a new receipt bound to the evidence receipt and, when selected, the exact content-addressed output-revision descriptor. Corrections are separate artifacts and never mutate prior receipts. |
|
|
25
|
+
| bounded cross-Work review | `HarnessEvaluationReviewReceipt` | Select only currently authorized immutable evidence, advance one watermark, group one stable claim, route to the smallest correct layer, and name the next authority without performing downstream effects. |
|
|
26
|
+
| model-improvement qualification | `ModelImprovementQualificationReceipt` | Bind the originating review, exact Harness, Taskset, real baseline Evaluation, Model, Environment/tool/permission/policy hashes, Verifier, source policies, privacy, budget, and non-frozen signal. Weak or confounded evidence emits `no_training`; training and activation remain host effects. |
|
|
19
27
|
|
|
20
28
|
## Compatibility policy
|
|
21
29
|
|
|
@@ -26,6 +34,17 @@ authorization, model streaming, artifact bytes, and runtime processes.
|
|
|
26
34
|
- Compatible package releases may add optional helpers and exports. Changing a
|
|
27
35
|
required field, identity hash, or privacy boundary requires a new schema
|
|
28
36
|
literal and an explicit normalizer.
|
|
37
|
+
- `openpond.agentSnapshot.v2`, `openpond.harnessRelease.v2`, and
|
|
38
|
+
`openpond.tasksetRelease.v2` define the Harness-first boundary. The v2
|
|
39
|
+
contracts remove the Profile reference from the Agent snapshot and keep the
|
|
40
|
+
Taskset independent of a concrete Harness, environment, or policy binding.
|
|
41
|
+
- Runs with different Harness releases require an explicit
|
|
42
|
+
`HarnessCompatibilityReceipt` binding both Harnesses to the same Taskset and
|
|
43
|
+
recording environment, tool, policy, and grader-interface contract hashes.
|
|
44
|
+
Callers with materialized releases should use
|
|
45
|
+
`createVerifiedHarnessCompatibilityReceipt`; it derives those hashes from the
|
|
46
|
+
immutable objects and rejects lifecycle, tool, grader-interface, or required
|
|
47
|
+
Environment-tool drift before issuing the receipt.
|
|
29
48
|
- The initial support target is Node.js ESM on Node 22.14 through Node 24.
|
|
30
49
|
- Portable paths are relative and at most 2,000 characters. Individual assets
|
|
31
50
|
are at most 250 MB. Tasksets, traces, and evidence arrays have schema-level
|
package/README.md
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
# `@openpond/evals`
|
|
2
2
|
|
|
3
|
-
Portable
|
|
4
|
-
|
|
5
|
-
Work
|
|
3
|
+
Portable evaluation contracts and pure helpers for Tasksets, graders, run
|
|
4
|
+
manifests, attempt and evaluation receipts, execution adapters, conformance
|
|
5
|
+
fixtures, Work-evidence eligibility, and no-training/SFT/preference/RL
|
|
6
|
+
qualification receipts. The package depends on
|
|
7
|
+
[`@openpond/harness`](../harness/README.md) for exact Harness identities but
|
|
8
|
+
does not re-export Harness APIs. Applications import the two packages directly,
|
|
9
|
+
which keeps refinement and evaluation authority visibly separate.
|
|
6
10
|
|
|
7
11
|
```ts
|
|
8
12
|
import {
|
|
9
13
|
AttemptReceiptSchema,
|
|
10
|
-
HarnessReleaseSchema,
|
|
11
14
|
TasksetReleaseSchema,
|
|
15
|
+
ModelImprovementQualificationReceiptSchema,
|
|
12
16
|
validateTasksetRelease,
|
|
13
17
|
verifyAttemptReceipt,
|
|
14
18
|
} from "@openpond/evals";
|
|
15
19
|
|
|
20
|
+
import { HarnessReleaseSchema } from "@openpond/harness";
|
|
21
|
+
|
|
16
22
|
import {
|
|
17
23
|
WorkEvidenceReceiptSchema,
|
|
18
24
|
classifyWorkEvidence,
|
|
@@ -21,9 +27,22 @@ import {
|
|
|
21
27
|
```
|
|
22
28
|
|
|
23
29
|
Subpath exports are available at `/harness`, `/tasksets`, `/graders`, `/runs`,
|
|
24
|
-
`/conformance`,
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
`/conformance`, `/evidence`, `/review`, and
|
|
31
|
+
`/model-improvement-qualification`. The package is an evaluation protocol library,
|
|
32
|
+
not a hosted client. It does not execute OpenPond Desktop or Sandbox sessions,
|
|
33
|
+
resolve credentials, or persist artifacts.
|
|
34
|
+
|
|
35
|
+
## Harness Evaluation review
|
|
36
|
+
|
|
37
|
+
`@openpond/harness` owns the public model-driven Refiner and continuous-review
|
|
38
|
+
policy plus immutable bounded decisions and receipts. Evals does not own
|
|
39
|
+
learning prompts, evidence selection, scheduling, or Harness mutation. It
|
|
40
|
+
binds an accepted review to the exact Harness, Taskset, scored
|
|
41
|
+
baseline Evaluation, base Model, Environment/tool/permission/policy hashes,
|
|
42
|
+
Verifier, source-policy checks, privacy approval, budget approval, and eligible
|
|
43
|
+
non-frozen learning signal. Frozen Evaluation evidence is rejected as training
|
|
44
|
+
evidence. Weak, constant, confounded, uncalibrated, revoked, or incompletely
|
|
45
|
+
authorized signal produces `no_training`; it cannot qualify a managed run.
|
|
27
46
|
|
|
28
47
|
## Work evidence
|
|
29
48
|
|
|
@@ -66,7 +85,7 @@ overrides that state.
|
|
|
66
85
|
Implement `HarnessRuntime` for environment state and `HarnessExecutor` around
|
|
67
86
|
the host's existing model/Agent loop. Do not reimplement prompting, tool dispatch,
|
|
68
87
|
session persistence, cost accounting, cancellation, or cleanup in this package.
|
|
69
|
-
A
|
|
88
|
+
A step-based environment maps reset/step/observation semantics to the same
|
|
70
89
|
interfaces and keeps provider allocation, authentication, and cleanup in its host.
|
|
71
90
|
|
|
72
91
|
## Conformance
|
package/RELEASING.md
CHANGED
|
@@ -1,54 +1,22 @@
|
|
|
1
1
|
# Releasing `@openpond/evals`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- `openpond.agentSnapshot.v1`
|
|
8
|
-
- `openpond.harnessRelease.v1`
|
|
9
|
-
- `openpond.tasksetRelease.v1`
|
|
10
|
-
- `openpond.runManifest.v1`
|
|
11
|
-
- `openpond.attemptReceipt.v1`
|
|
12
|
-
- `openpond.harnessTrace.v1`
|
|
13
|
-
- `openpond.graderEvidence.v1`
|
|
14
|
-
- `openpond.evaluationResult.v1`
|
|
15
|
-
|
|
16
|
-
This branch prepares the additive Work evidence schemas for `0.2.0`:
|
|
17
|
-
|
|
18
|
-
- `openpond.workEvidenceReceipt.v1`
|
|
19
|
-
- `openpond.workProcessTrace.v1`
|
|
20
|
-
- `openpond.workFeedbackReceipt.v1`
|
|
21
|
-
- `openpond.workEvidenceEligibility.v1`
|
|
22
|
-
|
|
23
|
-
## Trusted publishing
|
|
24
|
-
|
|
25
|
-
The package already exists on npm and the `npm-production` environment is
|
|
26
|
-
configured for trusted publishing through `release-evals.yml`. Do not run a
|
|
27
|
-
manual `npm publish` or repeat the original bootstrap. The workflow uses its own
|
|
28
|
-
pinned npm version for trusted publication and provenance.
|
|
29
|
-
|
|
30
|
-
To inspect an already-published version:
|
|
3
|
+
`@openpond/evals` is the public evaluation package for OpenPond Harnesses. It
|
|
4
|
+
depends on `@openpond/harness` for exact Harness identities but exposes only
|
|
5
|
+
evaluation APIs. Publish the matching Harness peer before Evals so npm can
|
|
6
|
+
satisfy the declared range.
|
|
31
7
|
|
|
32
8
|
```bash
|
|
33
9
|
pnpm evals:check
|
|
34
|
-
npm trust list @openpond/evals
|
|
35
|
-
npm view @openpond/evals version dist.integrity dist.attestations
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Later releases
|
|
39
|
-
|
|
40
|
-
For releases that do not already carry an intentional version bump, merge
|
|
41
|
-
feature work without changing the package version. When the intended package
|
|
42
|
-
changes are on `master`, prepare a separate release from a clean current
|
|
43
|
-
`master` checkout:
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
10
|
pnpm release:evals:patch
|
|
47
11
|
# or release:evals:minor / release:evals:major
|
|
48
12
|
```
|
|
49
13
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
14
|
+
Merging a release PR triggers `release-evals.yml`, trusted npm publishing,
|
|
15
|
+
registry verification, provenance verification, and the package-specific tag.
|
|
16
|
+
Release notes must call out removal or movement of a public subpath and use the
|
|
17
|
+
appropriate semver increment.
|
|
18
|
+
|
|
19
|
+
Version `0.4.0` removes the retired Harness root barrel and
|
|
20
|
+
`./harness-improvements` / `./harness-workspaces` compatibility subpaths.
|
|
21
|
+
Consumers must import those public contracts from `@openpond/harness`; this is
|
|
22
|
+
an intentional breaking package-boundary correction.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { assertContentHash, contentHash } from "@openpond/harness";
|
|
2
|
+
import { HarnessReleaseSchema, } from "@openpond/harness";
|
|
3
|
+
import { createHarnessCompatibilityReceipt, } from "./runs.js";
|
|
4
|
+
import { TasksetReleaseSchema, } from "./tasksets.js";
|
|
5
|
+
export function createVerifiedHarnessCompatibilityReceipt(input) {
|
|
6
|
+
const base = HarnessReleaseSchema.parse(input.baseHarnessRelease);
|
|
7
|
+
const candidate = HarnessReleaseSchema.parse(input.candidateHarnessRelease);
|
|
8
|
+
const taskset = TasksetReleaseSchema.parse(input.tasksetRelease);
|
|
9
|
+
assertContentHash(base, "Base Harness release");
|
|
10
|
+
assertContentHash(candidate, "Candidate Harness release");
|
|
11
|
+
assertContentHash(taskset, "Taskset release");
|
|
12
|
+
requireSameContract("lifecycle", base.lifecycle, candidate.lifecycle);
|
|
13
|
+
requireSameContract("tool", base.tools, candidate.tools);
|
|
14
|
+
requireSameContract("grader interface", base.graderInterface, candidate.graderInterface);
|
|
15
|
+
const environmentTools = new Set(taskset.tools.map((tool) => tool.name));
|
|
16
|
+
const unsupportedTools = base.tools
|
|
17
|
+
.map((tool) => tool.name)
|
|
18
|
+
.filter((name) => !environmentTools.has(name));
|
|
19
|
+
if (unsupportedTools.length) {
|
|
20
|
+
throw new Error(`Harness compatibility failed: Taskset Environment does not provide ${unsupportedTools.join(", ")}.`);
|
|
21
|
+
}
|
|
22
|
+
return createHarnessCompatibilityReceipt({
|
|
23
|
+
schemaVersion: "openpond.harnessCompatibility.v1",
|
|
24
|
+
id: input.id,
|
|
25
|
+
baseHarnessRelease: { id: base.id, contentHash: base.contentHash },
|
|
26
|
+
candidateHarnessRelease: {
|
|
27
|
+
id: candidate.id,
|
|
28
|
+
contentHash: candidate.contentHash,
|
|
29
|
+
},
|
|
30
|
+
tasksetRelease: { id: taskset.id, contentHash: taskset.contentHash },
|
|
31
|
+
environmentHash: contentHash(taskset.environment),
|
|
32
|
+
toolContractHash: contentHash(taskset.tools),
|
|
33
|
+
policyHash: contentHash(taskset.policy),
|
|
34
|
+
graderInterfaceHash: contentHash({
|
|
35
|
+
harness: base.graderInterface,
|
|
36
|
+
taskset: taskset.graders,
|
|
37
|
+
}),
|
|
38
|
+
metadata: input.metadata ?? {},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function requireSameContract(label, base, candidate) {
|
|
42
|
+
if (contentHash(base) !== contentHash(candidate)) {
|
|
43
|
+
throw new Error(`Harness compatibility failed: ${label} contract changed.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
package/dist/conformance.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { contentHash, withContentHash } from "
|
|
2
|
-
import { createAgentSnapshot, createHarnessRelease } from "./harness.js";
|
|
1
|
+
import { contentHash, createAgentSnapshot, createHarnessRelease, withContentHash, } from "@openpond/harness";
|
|
3
2
|
import { createRunManifest } from "./runs.js";
|
|
4
3
|
import { TasksetReleaseSchema } from "./tasksets.js";
|
|
5
4
|
const EMPTY_HASH = contentHash("");
|
|
@@ -14,32 +13,29 @@ export const marketingPortfolioConformance = fixture("marketing-portfolio-v1", [
|
|
|
14
13
|
]);
|
|
15
14
|
function fixture(id, tools) {
|
|
16
15
|
const snapshot = createAgentSnapshot({
|
|
17
|
-
schemaVersion: "openpond.agentSnapshot.
|
|
16
|
+
schemaVersion: "openpond.agentSnapshot.v2",
|
|
18
17
|
id: `${id}-agent`,
|
|
19
|
-
|
|
18
|
+
sourceRelease: null,
|
|
20
19
|
instructions: [], skills: [], agents: [], toolDeclarations: tools,
|
|
21
20
|
capabilityRequirements: [], dependencyLock,
|
|
22
21
|
portability: { portable: true, blockers: [], localOnlyAssetRefs: [], hostPrivateAssetRefs: [] },
|
|
23
22
|
metadata: { conformanceFixture: id },
|
|
24
23
|
});
|
|
25
24
|
const harness = createHarnessRelease({
|
|
26
|
-
schemaVersion: "openpond.harnessRelease.
|
|
25
|
+
schemaVersion: "openpond.harnessRelease.v2",
|
|
27
26
|
id: `${id}-harness`,
|
|
28
27
|
agentSnapshot: { id: snapshot.id, contentHash: snapshot.contentHash },
|
|
29
28
|
program,
|
|
30
|
-
environment: { protocolVersion: "openpond.environment.v1", kind: "agent", entrypoint: id, stateful: true, deterministicSeeds: true, lifecycle: ["create", "reset", "step", "collect", "destroy"], networkPolicy: "none", defaultTimeoutMs: 5_000 },
|
|
31
29
|
tools,
|
|
32
30
|
lifecycle: { create: true, reset: true, step: true, collect: true, destroy: true, resetScope: "attempt" },
|
|
33
31
|
graderInterface: { visibleEvidence: ["output"], privilegedEvidence: ["expected"], privateVerifierIsolation: true },
|
|
34
|
-
policy: { policyVisibleFields: ["input"], privilegedFields: ["expectedOutput"], hiddenGraderRefs: [], connectedAppScopes: [] },
|
|
35
32
|
files: [], metadata: { conformanceFixture: id },
|
|
36
33
|
});
|
|
37
34
|
const tasksetContent = {
|
|
38
|
-
schemaVersion: "openpond.tasksetRelease.
|
|
35
|
+
schemaVersion: "openpond.tasksetRelease.v2",
|
|
39
36
|
id: `${id}-taskset`, revision: 1,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
environment: harness.environment,
|
|
37
|
+
policy: { policyVisibleFields: ["input"], privilegedFields: ["expectedOutput"], hiddenGraderRefs: [], connectedAppScopes: [] },
|
|
38
|
+
environment: { protocolVersion: "openpond.environment.v1", kind: "agent", entrypoint: id, stateful: true, deterministicSeeds: true, lifecycle: ["create", "reset", "step", "collect", "destroy"], networkPolicy: "none", defaultTimeoutMs: 5_000 },
|
|
43
39
|
tools,
|
|
44
40
|
capabilities: [],
|
|
45
41
|
tasks: [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { ImmutableReleaseRefSchema, ReleaseHashSchema } from "
|
|
2
|
+
import { ImmutableReleaseRefSchema, ReleaseHashSchema } from "@openpond/harness";
|
|
3
3
|
import { EvidenceArtifactRefSchema, WorkEvidenceReceiptSchema, evidenceArtifactRef, } from "./contracts.js";
|
|
4
4
|
import { WorkEvidenceEligibilitySchema } from "./eligibility.js";
|
|
5
5
|
export const WorkEvidenceAuthoringInputSchema = z.object({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { canonicalJson, contentHash } from "
|
|
1
|
+
import { canonicalJson, contentHash } from "@openpond/harness";
|
|
2
2
|
import { createWorkEvidenceReceipt, createWorkFeedbackReceipt, createWorkProcessTrace, evidenceArtifactRef, workEvidenceReceiptRef, workSourceOpaqueRef, } from "./contracts.js";
|
|
3
3
|
import { classifyWorkEvidence } from "./eligibility.js";
|
|
4
4
|
const startedAt = "2026-08-04T12:00:00.000Z";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { ImmutableArtifactRefSchema, ImmutableReleaseRefSchema, ReleaseHashSchema, ReleaseIdSchema, ReleaseTimestampSchema, contentHash, } from "
|
|
3
|
-
import { ModelRefSchema } from "../runs.js";
|
|
2
|
+
import { ImmutableArtifactRefSchema, ImmutableReleaseRefSchema, ModelRefSchema, ReleaseHashSchema, ReleaseIdSchema, ReleaseTimestampSchema, contentHash, } from "@openpond/harness";
|
|
4
3
|
export const WORK_EVIDENCE_SCHEMA_VERSION = "openpond.workEvidenceReceipt.v1";
|
|
5
4
|
export const WORK_PROCESS_TRACE_SCHEMA_VERSION = "openpond.workProcessTrace.v1";
|
|
6
5
|
export const WORK_FEEDBACK_SCHEMA_VERSION = "openpond.workFeedbackReceipt.v1";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { contentHash, ReleaseHashSchema } from "
|
|
2
|
+
import { contentHash, ReleaseHashSchema } from "@openpond/harness";
|
|
3
3
|
import { AttemptReceiptSchema, verifyAttemptReceipt } from "../runs.js";
|
|
4
4
|
import { WORK_EVIDENCE_ELIGIBILITY_SCHEMA_VERSION, WorkFeedbackReceiptSchema, createWorkFeedbackReceipt, verifyWorkEvidenceReceipt, } from "./contracts.js";
|
|
5
5
|
export const WorkEvidencePolicyStateSchema = z.enum([
|
package/dist/graders.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { FailureClassSchema, ReleaseHashSchema, ReleaseIdSchema, contentHash } from "
|
|
2
|
+
import { FailureClassSchema, ReleaseHashSchema, ReleaseIdSchema, contentHash } from "@openpond/harness";
|
|
3
3
|
export const GraderEvidenceContentSchema = z.object({
|
|
4
4
|
schemaVersion: z.literal("openpond.graderEvidence.v1"),
|
|
5
5
|
graderId: ReleaseIdSchema,
|
package/dist/harness.js
CHANGED
|
@@ -1,73 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { createAttemptReceipt } from "./runs.js";
|
|
5
|
-
export const PortabilityReportSchema = z.object({
|
|
6
|
-
portable: z.boolean(),
|
|
7
|
-
blockers: z.array(z.string().trim().min(1).max(2_000)).max(1_000),
|
|
8
|
-
localOnlyAssetRefs: z.array(ReleaseIdSchema).max(10_000),
|
|
9
|
-
hostPrivateAssetRefs: z.array(ReleaseIdSchema).max(10_000),
|
|
10
|
-
}).strict();
|
|
11
|
-
export const AgentSnapshotContentSchema = z.object({
|
|
12
|
-
schemaVersion: z.literal("openpond.agentSnapshot.v1"),
|
|
13
|
-
id: ReleaseIdSchema,
|
|
14
|
-
profileRelease: ImmutableReleaseRefSchema.nullable(),
|
|
15
|
-
instructions: z.array(ImmutableAssetRefSchema).max(10_000),
|
|
16
|
-
skills: z.array(ImmutableAssetRefSchema).max(10_000),
|
|
17
|
-
agents: z.array(ImmutableAssetRefSchema).max(10_000),
|
|
18
|
-
toolDeclarations: z.array(ToolDeclarationSchema).max(200),
|
|
19
|
-
capabilityRequirements: z.array(z.object({
|
|
20
|
-
id: ReleaseIdSchema,
|
|
21
|
-
required: z.boolean(),
|
|
22
|
-
scopes: z.array(z.string().trim().min(1).max(500)).max(100),
|
|
23
|
-
}).strict()).max(200),
|
|
24
|
-
dependencyLock: ImmutableAssetRefSchema,
|
|
25
|
-
portability: PortabilityReportSchema,
|
|
26
|
-
metadata: MetadataSchema,
|
|
27
|
-
}).strict();
|
|
28
|
-
export const AgentSnapshotSchema = AgentSnapshotContentSchema.extend({ contentHash: ReleaseHashSchema }).strict();
|
|
29
|
-
export const LifecycleContractSchema = z.object({
|
|
30
|
-
create: z.literal(true),
|
|
31
|
-
reset: z.literal(true),
|
|
32
|
-
step: z.literal(true),
|
|
33
|
-
collect: z.literal(true),
|
|
34
|
-
destroy: z.literal(true),
|
|
35
|
-
resetScope: z.enum(["task", "attempt"]),
|
|
36
|
-
}).strict();
|
|
37
|
-
export const GraderInterfaceContractSchema = z.object({
|
|
38
|
-
visibleEvidence: z.array(ReleaseIdSchema).max(1_000),
|
|
39
|
-
privilegedEvidence: z.array(ReleaseIdSchema).max(1_000),
|
|
40
|
-
privateVerifierIsolation: z.boolean(),
|
|
41
|
-
}).strict();
|
|
42
|
-
export const HarnessReleaseContentSchema = z.object({
|
|
43
|
-
schemaVersion: z.literal("openpond.harnessRelease.v1"),
|
|
44
|
-
id: ReleaseIdSchema,
|
|
45
|
-
agentSnapshot: ImmutableReleaseRefSchema,
|
|
46
|
-
program: ImmutableAssetRefSchema,
|
|
47
|
-
environment: EnvironmentContractSchema,
|
|
48
|
-
tools: z.array(ToolDeclarationSchema).max(200),
|
|
49
|
-
lifecycle: LifecycleContractSchema,
|
|
50
|
-
graderInterface: GraderInterfaceContractSchema,
|
|
51
|
-
policy: PolicyBoundarySchema,
|
|
52
|
-
files: z.array(ImmutableAssetRefSchema).max(100_000),
|
|
53
|
-
metadata: MetadataSchema,
|
|
54
|
-
}).strict();
|
|
55
|
-
export const HarnessReleaseSchema = HarnessReleaseContentSchema.extend({ contentHash: ReleaseHashSchema }).strict();
|
|
56
|
-
export const ModelActionSchema = z.object({
|
|
57
|
-
id: ReleaseIdSchema,
|
|
58
|
-
turn: z.number().int().nonnegative(),
|
|
59
|
-
kind: z.enum(["message", "tool_call", "terminal"]),
|
|
60
|
-
name: ReleaseIdSchema.nullable(),
|
|
61
|
-
arguments: z.record(z.string(), z.unknown()),
|
|
62
|
-
content: z.string().max(1_000_000).nullable(),
|
|
63
|
-
}).strict();
|
|
64
|
-
export const ToolObservationSchema = z.object({
|
|
65
|
-
actionId: ReleaseIdSchema,
|
|
66
|
-
turn: z.number().int().nonnegative(),
|
|
67
|
-
terminal: z.boolean(),
|
|
68
|
-
output: z.record(z.string(), z.unknown()),
|
|
69
|
-
artifactRefs: z.array(ImmutableArtifactRefSchema).max(100_000),
|
|
70
|
-
}).strict();
|
|
1
|
+
import { HarnessTraceSchema, ModelActionSchema, ToolObservationSchema, contentHash, } from "@openpond/harness";
|
|
2
|
+
import { createAttemptReceipt, } from "./runs.js";
|
|
3
|
+
export * from "@openpond/harness/harness";
|
|
71
4
|
export async function executeRuntimeProtocol(input) {
|
|
72
5
|
const now = input.now ?? (() => new Date().toISOString());
|
|
73
6
|
const startedAt = now();
|
|
@@ -86,12 +19,25 @@ export async function executeRuntimeProtocol(input) {
|
|
|
86
19
|
let output = {};
|
|
87
20
|
let artifactRefs = [];
|
|
88
21
|
const event = (type, payload, metadata = {}) => {
|
|
89
|
-
events.push({
|
|
22
|
+
events.push({
|
|
23
|
+
sequence: sequence++,
|
|
24
|
+
type,
|
|
25
|
+
payloadHash: contentHash(payload),
|
|
26
|
+
metadata,
|
|
27
|
+
});
|
|
90
28
|
};
|
|
91
29
|
try {
|
|
92
|
-
lease = await input.runtime.create({
|
|
30
|
+
lease = await input.runtime.create({
|
|
31
|
+
manifest: input.manifest,
|
|
32
|
+
taskId: input.taskId,
|
|
33
|
+
seed: input.seed,
|
|
34
|
+
signal: controller.signal,
|
|
35
|
+
});
|
|
93
36
|
event("created", { leaseId: lease.id });
|
|
94
|
-
await input.runtime.reset(lease, {
|
|
37
|
+
await input.runtime.reset(lease, {
|
|
38
|
+
seed: input.seed,
|
|
39
|
+
signal: controller.signal,
|
|
40
|
+
});
|
|
95
41
|
event("reset", { seed: input.seed });
|
|
96
42
|
for (const candidate of input.actions.slice(0, input.manifest.limits.maxTurns)) {
|
|
97
43
|
if (controller.signal.aborted)
|
|
@@ -154,12 +100,23 @@ export async function executeRuntimeProtocol(input) {
|
|
|
154
100
|
failureClass,
|
|
155
101
|
output,
|
|
156
102
|
};
|
|
157
|
-
const trace = HarnessTraceSchema.parse({
|
|
103
|
+
const trace = HarnessTraceSchema.parse({
|
|
104
|
+
...traceContent,
|
|
105
|
+
contentHash: contentHash(traceContent),
|
|
106
|
+
});
|
|
158
107
|
const completedAt = now();
|
|
159
108
|
const receipt = createAttemptReceipt({
|
|
160
109
|
schemaVersion: "openpond.attemptReceipt.v1",
|
|
161
|
-
id: `attempt-${contentHash([
|
|
162
|
-
|
|
110
|
+
id: `attempt-${contentHash([
|
|
111
|
+
input.manifest.contentHash,
|
|
112
|
+
input.taskId,
|
|
113
|
+
input.seed,
|
|
114
|
+
trace.contentHash,
|
|
115
|
+
]).slice(0, 24)}`,
|
|
116
|
+
runManifest: {
|
|
117
|
+
id: input.manifest.id,
|
|
118
|
+
contentHash: input.manifest.contentHash,
|
|
119
|
+
},
|
|
163
120
|
taskId: input.taskId,
|
|
164
121
|
seed: input.seed,
|
|
165
122
|
terminal,
|
|
@@ -177,30 +134,3 @@ export async function executeRuntimeProtocol(input) {
|
|
|
177
134
|
});
|
|
178
135
|
return { receipt, trace, output };
|
|
179
136
|
}
|
|
180
|
-
export function createAgentSnapshot(input) {
|
|
181
|
-
const content = AgentSnapshotContentSchema.parse(input);
|
|
182
|
-
return AgentSnapshotSchema.parse({ ...content, contentHash: contentHash(content) });
|
|
183
|
-
}
|
|
184
|
-
export function createHarnessRelease(input) {
|
|
185
|
-
const content = HarnessReleaseContentSchema.parse(input);
|
|
186
|
-
return HarnessReleaseSchema.parse({ ...content, contentHash: contentHash(content) });
|
|
187
|
-
}
|
|
188
|
-
export const HarnessLifecycleEventSchema = z.object({
|
|
189
|
-
sequence: z.number().int().nonnegative(),
|
|
190
|
-
type: z.enum(["created", "reset", "action", "observation", "terminal", "failure", "collected", "destroyed"]),
|
|
191
|
-
payloadHash: ReleaseHashSchema,
|
|
192
|
-
metadata: MetadataSchema,
|
|
193
|
-
}).strict();
|
|
194
|
-
export const HarnessTraceSchema = z.object({
|
|
195
|
-
schemaVersion: z.literal("openpond.harnessTrace.v1"),
|
|
196
|
-
manifest: ImmutableReleaseRefSchema,
|
|
197
|
-
taskId: ReleaseIdSchema,
|
|
198
|
-
seed: z.string().trim().min(1).max(500),
|
|
199
|
-
events: z.array(HarnessLifecycleEventSchema).max(1_000_000),
|
|
200
|
-
actions: z.array(ModelActionSchema).max(100_000),
|
|
201
|
-
observations: z.array(ToolObservationSchema).max(100_000),
|
|
202
|
-
terminal: z.boolean(),
|
|
203
|
-
failureClass: FailureClassSchema.nullable(),
|
|
204
|
-
output: z.record(z.string(), z.unknown()),
|
|
205
|
-
contentHash: ReleaseHashSchema,
|
|
206
|
-
}).strict();
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./compatibility.js";
|
|
2
2
|
export * from "./evidence/index.js";
|
|
3
3
|
export * from "./graders.js";
|
|
4
4
|
export * from "./harness.js";
|
|
5
5
|
export * from "./runs.js";
|
|
6
|
+
export * from "./model-improvement-qualification.js";
|
|
7
|
+
export * from "./review-conformance.js";
|
|
6
8
|
export * from "./tasksets.js";
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { HarnessReviewSourcePolicyRefSchema, ImmutableReleaseRefSchema, MetadataSchema, ModelRefSchema, ReleaseHashSchema, ReleaseIdSchema, ReleaseTimestampSchema, contentHash, } from "@openpond/harness";
|
|
3
|
+
const BoundedTextSchema = z.string().trim().min(1).max(100_000);
|
|
4
|
+
export const ModelImprovementDecisionSchema = z.enum([
|
|
5
|
+
"no_training",
|
|
6
|
+
"sft",
|
|
7
|
+
"preference",
|
|
8
|
+
"rl",
|
|
9
|
+
]);
|
|
10
|
+
export const ModelImprovementSignalSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
kind: z.enum(["none", "demonstrations", "chosen_rejected", "scalar_reward"]),
|
|
13
|
+
strength: z.enum(["absent", "weak", "usable"]),
|
|
14
|
+
calibrated: z.boolean(),
|
|
15
|
+
confounded: z.boolean(),
|
|
16
|
+
variance: z.number().finite().nonnegative().nullable(),
|
|
17
|
+
evidenceRefs: z.array(ImmutableReleaseRefSchema).max(100_000),
|
|
18
|
+
})
|
|
19
|
+
.strict();
|
|
20
|
+
export const ModelImprovementQualificationReceiptContentSchema = z
|
|
21
|
+
.object({
|
|
22
|
+
schemaVersion: z.literal("openpond.modelImprovementQualificationReceipt.v1"),
|
|
23
|
+
id: ReleaseIdSchema,
|
|
24
|
+
review: ImmutableReleaseRefSchema,
|
|
25
|
+
harnessRelease: ImmutableReleaseRefSchema,
|
|
26
|
+
tasksetRelease: ImmutableReleaseRefSchema.nullable(),
|
|
27
|
+
baselineEvaluation: ImmutableReleaseRefSchema.nullable(),
|
|
28
|
+
model: ModelRefSchema,
|
|
29
|
+
environmentHash: ReleaseHashSchema.nullable(),
|
|
30
|
+
toolContractHash: ReleaseHashSchema.nullable(),
|
|
31
|
+
permissionContractHash: ReleaseHashSchema.nullable(),
|
|
32
|
+
policyHash: ReleaseHashSchema.nullable(),
|
|
33
|
+
verifierRef: ImmutableReleaseRefSchema.nullable(),
|
|
34
|
+
sourcePolicies: z.array(HarnessReviewSourcePolicyRefSchema).max(10_000),
|
|
35
|
+
trainingEvidenceRefs: z.array(ImmutableReleaseRefSchema).max(100_000),
|
|
36
|
+
frozenEvaluationEvidenceRefs: z.array(ImmutableReleaseRefSchema).max(100_000),
|
|
37
|
+
privacyApproval: ImmutableReleaseRefSchema.nullable(),
|
|
38
|
+
budgetApproval: ImmutableReleaseRefSchema.nullable(),
|
|
39
|
+
maximumCostUsd: z.number().finite().nonnegative(),
|
|
40
|
+
signal: ModelImprovementSignalSchema,
|
|
41
|
+
decision: ModelImprovementDecisionSchema,
|
|
42
|
+
reasons: z.array(BoundedTextSchema).min(1).max(100),
|
|
43
|
+
createdAt: ReleaseTimestampSchema,
|
|
44
|
+
metadata: MetadataSchema,
|
|
45
|
+
})
|
|
46
|
+
.strict()
|
|
47
|
+
.superRefine((receipt, context) => {
|
|
48
|
+
const trainingKeys = new Set(receipt.trainingEvidenceRefs.map(refKey));
|
|
49
|
+
if (receipt.frozenEvaluationEvidenceRefs.some((reference) => trainingKeys.has(refKey(reference)))) {
|
|
50
|
+
context.addIssue({
|
|
51
|
+
code: "custom",
|
|
52
|
+
message: "frozen Evaluation evidence cannot be used as training evidence",
|
|
53
|
+
path: ["frozenEvaluationEvidenceRefs"],
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (receipt.decision === "no_training")
|
|
57
|
+
return;
|
|
58
|
+
const missingGate = !receipt.tasksetRelease ||
|
|
59
|
+
!receipt.baselineEvaluation ||
|
|
60
|
+
!receipt.environmentHash ||
|
|
61
|
+
!receipt.toolContractHash ||
|
|
62
|
+
!receipt.permissionContractHash ||
|
|
63
|
+
!receipt.policyHash ||
|
|
64
|
+
!receipt.verifierRef ||
|
|
65
|
+
!receipt.privacyApproval ||
|
|
66
|
+
!receipt.budgetApproval ||
|
|
67
|
+
receipt.sourcePolicies.length === 0 ||
|
|
68
|
+
receipt.sourcePolicies.some((policy) => policy.state !== "authorized") ||
|
|
69
|
+
receipt.trainingEvidenceRefs.length === 0 ||
|
|
70
|
+
receipt.signal.strength !== "usable" ||
|
|
71
|
+
!receipt.signal.calibrated ||
|
|
72
|
+
receipt.signal.confounded;
|
|
73
|
+
if (missingGate) {
|
|
74
|
+
context.addIssue({
|
|
75
|
+
code: "custom",
|
|
76
|
+
message: "qualified model improvement requires frozen lineage, authorized signal, privacy, and budget gates",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (receipt.decision === "sft" &&
|
|
80
|
+
receipt.signal.kind !== "demonstrations") {
|
|
81
|
+
context.addIssue({
|
|
82
|
+
code: "custom",
|
|
83
|
+
message: "SFT qualification requires demonstration signal",
|
|
84
|
+
path: ["signal", "kind"],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (receipt.decision === "preference" &&
|
|
88
|
+
receipt.signal.kind !== "chosen_rejected") {
|
|
89
|
+
context.addIssue({
|
|
90
|
+
code: "custom",
|
|
91
|
+
message: "preference qualification requires chosen/rejected signal",
|
|
92
|
+
path: ["signal", "kind"],
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (receipt.decision === "rl" &&
|
|
96
|
+
(receipt.signal.kind !== "scalar_reward" ||
|
|
97
|
+
receipt.signal.variance === null ||
|
|
98
|
+
receipt.signal.variance <= 0)) {
|
|
99
|
+
context.addIssue({
|
|
100
|
+
code: "custom",
|
|
101
|
+
message: "RL qualification requires a usable scalar reward with variance",
|
|
102
|
+
path: ["signal"],
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
export const ModelImprovementQualificationReceiptSchema = ModelImprovementQualificationReceiptContentSchema.extend({
|
|
107
|
+
contentHash: ReleaseHashSchema,
|
|
108
|
+
}).strict();
|
|
109
|
+
export function createModelImprovementQualificationReceipt(input) {
|
|
110
|
+
const content = ModelImprovementQualificationReceiptContentSchema.parse(input);
|
|
111
|
+
return ModelImprovementQualificationReceiptSchema.parse({
|
|
112
|
+
...content,
|
|
113
|
+
contentHash: contentHash(content),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
export function verifyModelImprovementQualificationReceipt(value) {
|
|
117
|
+
const parsed = ModelImprovementQualificationReceiptSchema.safeParse(value);
|
|
118
|
+
if (!parsed.success)
|
|
119
|
+
return false;
|
|
120
|
+
const { contentHash: actual, ...content } = parsed.data;
|
|
121
|
+
return (contentHash(ModelImprovementQualificationReceiptContentSchema.parse(content)) === actual);
|
|
122
|
+
}
|
|
123
|
+
function refKey(reference) {
|
|
124
|
+
return `${reference.id}:${reference.contentHash}`;
|
|
125
|
+
}
|