@jinn-network/core 0.1.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/dist/canonical-json.d.ts +1 -0
- package/dist/canonical-json.js +67 -0
- package/dist/captured-task.d.ts +140 -0
- package/dist/captured-task.js +122 -0
- package/dist/contribution-store.d.ts +97 -0
- package/dist/contribution-store.js +770 -0
- package/dist/corpus-read/acquire.d.ts +39 -0
- package/dist/corpus-read/acquire.js +212 -0
- package/dist/corpus-read/cache.d.ts +14 -0
- package/dist/corpus-read/cache.js +17 -0
- package/dist/corpus-read/capture-meta.d.ts +16 -0
- package/dist/corpus-read/capture-meta.js +18 -0
- package/dist/corpus-read/create-corpus.d.ts +2 -0
- package/dist/corpus-read/create-corpus.js +97 -0
- package/dist/corpus-read/fetch-artifact.d.ts +21 -0
- package/dist/corpus-read/fetch-artifact.js +32 -0
- package/dist/corpus-read/fetch.d.ts +12 -0
- package/dist/corpus-read/fetch.js +24 -0
- package/dist/corpus-read/http-discovery.d.ts +9 -0
- package/dist/corpus-read/http-discovery.js +128 -0
- package/dist/corpus-read/index.d.ts +10 -0
- package/dist/corpus-read/index.js +10 -0
- package/dist/corpus-read/ipfs.d.ts +5 -0
- package/dist/corpus-read/ipfs.js +72 -0
- package/dist/corpus-read/route-resolver.d.ts +16 -0
- package/dist/corpus-read/route-resolver.js +19 -0
- package/dist/corpus-read/types.d.ts +177 -0
- package/dist/corpus-read/types.js +42 -0
- package/dist/envelope.d.ts +134 -0
- package/dist/envelope.js +162 -0
- package/dist/evidence-adapter.d.ts +26 -0
- package/dist/evidence-adapter.js +321 -0
- package/dist/evidence-filesystem.d.ts +40 -0
- package/dist/evidence-filesystem.js +267 -0
- package/dist/evidence-index.d.ts +117 -0
- package/dist/evidence-index.js +1083 -0
- package/dist/evidence-store-lock.d.ts +2 -0
- package/dist/evidence-store-lock.js +208 -0
- package/dist/execution-envelope.d.ts +3142 -0
- package/dist/execution-envelope.js +203 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/manifest.d.ts +75 -0
- package/dist/manifest.js +184 -0
- package/dist/paired.d.ts +68 -0
- package/dist/paired.js +92 -0
- package/dist/scrub/build.d.ts +52 -0
- package/dist/scrub/build.js +84 -0
- package/dist/scrub/emit-scrub.d.ts +41 -0
- package/dist/scrub/emit-scrub.js +87 -0
- package/dist/scrub/index.d.ts +12 -0
- package/dist/scrub/index.js +12 -0
- package/dist/scrub/key-policy.d.ts +20 -0
- package/dist/scrub/key-policy.js +42 -0
- package/dist/scrub/layer2.d.ts +23 -0
- package/dist/scrub/layer2.js +32 -0
- package/dist/scrub/ml-pii-stage.d.ts +24 -0
- package/dist/scrub/ml-pii-stage.js +42 -0
- package/dist/scrub/openredaction-stage.d.ts +196 -0
- package/dist/scrub/openredaction-stage.js +270 -0
- package/dist/scrub/pii-build.d.ts +38 -0
- package/dist/scrub/pii-build.js +67 -0
- package/dist/scrub/pipeline.d.ts +38 -0
- package/dist/scrub/pipeline.js +83 -0
- package/dist/scrub/plain-patterns-stage.d.ts +31 -0
- package/dist/scrub/plain-patterns-stage.js +84 -0
- package/dist/scrub/secretlint-stage.d.ts +36 -0
- package/dist/scrub/secretlint-stage.js +249 -0
- package/dist/scrub/transformers-detector.d.ts +35 -0
- package/dist/scrub/transformers-detector.js +67 -0
- package/dist/scrub/types.d.ts +25 -0
- package/dist/scrub/types.js +1 -0
- package/dist/session-provenance.d.ts +75 -0
- package/dist/session-provenance.js +20 -0
- package/dist/skill-artifact.d.ts +442 -0
- package/dist/skill-artifact.js +136 -0
- package/dist/trajectory/hash-chain.d.ts +18 -0
- package/dist/trajectory/hash-chain.js +47 -0
- package/dist/trajectory/index.d.ts +4 -0
- package/dist/trajectory/index.js +4 -0
- package/dist/trajectory/schema.d.ts +606 -0
- package/dist/trajectory/schema.js +110 -0
- package/dist/trajectory/transcript-parsers/aider-history.d.ts +42 -0
- package/dist/trajectory/transcript-parsers/aider-history.js +181 -0
- package/dist/trajectory/transcript-parsers/claude-code-jsonl.d.ts +37 -0
- package/dist/trajectory/transcript-parsers/claude-code-jsonl.js +142 -0
- package/dist/trajectory/transcript-parsers/codex-session.d.ts +42 -0
- package/dist/trajectory/transcript-parsers/codex-session.js +235 -0
- package/dist/trajectory/transcript-parsers/continue-devdata.d.ts +41 -0
- package/dist/trajectory/transcript-parsers/continue-devdata.js +190 -0
- package/dist/trajectory/transcript-parsers/cursor-sqlite.d.ts +38 -0
- package/dist/trajectory/transcript-parsers/cursor-sqlite.js +118 -0
- package/dist/trajectory/transcript-parsers/gemini-session.d.ts +35 -0
- package/dist/trajectory/transcript-parsers/gemini-session.js +137 -0
- package/dist/trajectory/transcript-parsers/index.d.ts +7 -0
- package/dist/trajectory/transcript-parsers/index.js +7 -0
- package/dist/trajectory/transcript-parsers/types.d.ts +101 -0
- package/dist/trajectory/transcript-parsers/types.js +32 -0
- package/dist/trajectory/transcript-to-spans/attrs.d.ts +4 -0
- package/dist/trajectory/transcript-to-spans/attrs.js +30 -0
- package/dist/trajectory/transcript-to-spans/claude-code-stream-json.d.ts +8 -0
- package/dist/trajectory/transcript-to-spans/claude-code-stream-json.js +162 -0
- package/dist/trajectory/transcript-to-spans/codex-exec-json.d.ts +8 -0
- package/dist/trajectory/transcript-to-spans/codex-exec-json.js +253 -0
- package/dist/trajectory/transcript-to-spans/index.d.ts +4 -0
- package/dist/trajectory/transcript-to-spans/index.js +4 -0
- package/dist/trajectory/transcript-to-spans/types.d.ts +18 -0
- package/dist/trajectory/transcript-to-spans/types.js +1 -0
- package/dist/window.d.ts +12 -0
- package/dist/window.js +5 -0
- package/package.json +67 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function canonicalJson(value: unknown): string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical JSON serialisation — RFC 8785 JCS.
|
|
3
|
+
*
|
|
4
|
+
* Uses the `canonicalize` npm package (≈30 LOC, zero deps) so third-party
|
|
5
|
+
* verifiers can reproduce our signing input with any standard JCS library.
|
|
6
|
+
*
|
|
7
|
+
* Rules per RFC 8785:
|
|
8
|
+
* - Object keys sorted lexicographically by UTF-16 code-unit order.
|
|
9
|
+
* - No insignificant whitespace.
|
|
10
|
+
* - I-JSON number formatting per ECMAScript `Number.prototype.toString(10)`
|
|
11
|
+
* (integer-preferred; scientific notation when |x| ≥ 1e21 or |x| < 5e-7;
|
|
12
|
+
* -0 serialises as 0).
|
|
13
|
+
* - String escape rules per JSON spec (control chars as \\uXXXX; only ", \
|
|
14
|
+
* and control chars must be escaped).
|
|
15
|
+
* - `undefined` values in objects are dropped (matches JSON.stringify).
|
|
16
|
+
* - `NaN` / `Infinity` serialise to `null` (matches JSON.stringify).
|
|
17
|
+
*
|
|
18
|
+
* BigInt is **not** supported — JCS is a canonicalization of standard JSON,
|
|
19
|
+
* which has no BigInt type. Callers must convert BigInt to string or number
|
|
20
|
+
* before calling. Passing BigInt throws.
|
|
21
|
+
*
|
|
22
|
+
* Used for manifest signing: produce a deterministic byte string that two
|
|
23
|
+
* independent parties can reproduce from the same object graph.
|
|
24
|
+
*/
|
|
25
|
+
// canonicalize v3 is ESM-only (no CJS entry); the client is `"type": "module"`
|
|
26
|
+
// so a native ESM default import is the correct interop (replaces the v2-era
|
|
27
|
+
// createRequire shim). v3 is packaging-only vs v2 — its RFC 8785 output is
|
|
28
|
+
// byte-identical, so existing content hashes / manifest signatures are stable.
|
|
29
|
+
import canonicalize from 'canonicalize';
|
|
30
|
+
/**
|
|
31
|
+
* Recursively replace NaN / ±Infinity with null so that canonicalize does not
|
|
32
|
+
* throw — matching the JSON.stringify behaviour that the rest of the codebase
|
|
33
|
+
* expects. BigInt is intentionally left unhandled so that canonicalize throws
|
|
34
|
+
* a clear error when a caller passes one.
|
|
35
|
+
*/
|
|
36
|
+
function coerceNonFinite(value) {
|
|
37
|
+
if (typeof value === 'number' && !isFinite(value))
|
|
38
|
+
return null;
|
|
39
|
+
if (Array.isArray(value))
|
|
40
|
+
return value.map(coerceNonFinite);
|
|
41
|
+
if (value !== null && typeof value === 'object') {
|
|
42
|
+
// Preserve toJSON() — canonicalize would otherwise call it itself;
|
|
43
|
+
// by pre-processing we must not strip it. Invoke it here and recurse
|
|
44
|
+
// on its return value so NaN/Infinity inside toJSON results are still
|
|
45
|
+
// coerced.
|
|
46
|
+
const toJson = value.toJSON;
|
|
47
|
+
if (typeof toJson === 'function') {
|
|
48
|
+
return coerceNonFinite(toJson.call(value));
|
|
49
|
+
}
|
|
50
|
+
const out = {};
|
|
51
|
+
for (const [k, v] of Object.entries(value))
|
|
52
|
+
out[k] = coerceNonFinite(v);
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
export function canonicalJson(value) {
|
|
58
|
+
const coerced = coerceNonFinite(value);
|
|
59
|
+
const result = canonicalize(coerced);
|
|
60
|
+
if (result === undefined) {
|
|
61
|
+
// canonicalize returns undefined for top-level undefined input (matches
|
|
62
|
+
// JSON.stringify). Match Jinn's previous behaviour: emit "null" so the
|
|
63
|
+
// return type is always a string.
|
|
64
|
+
return 'null';
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captured-task schema — the raw, pre-scrub input to the harness capture path.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from the former client harness layer in C2 (#1833):
|
|
5
|
+
* the parse half of capture.ts has no scrub / `client/src` dependency (only
|
|
6
|
+
* zod + the two envelope enums), so it moved into `@jinn-network/core`.
|
|
7
|
+
* C5 subsequently moved the scrub implementation alongside it while leaving
|
|
8
|
+
* capture orchestration in the layer.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
/**
|
|
12
|
+
* A captured task — the raw, pre-scrub input to `capture()`. Mirrors the
|
|
13
|
+
* envelope shape minus `consent` (which does not exist pre-consent) with
|
|
14
|
+
* UNSCRUBBED step attributes and no size caps (raw captures routinely exceed
|
|
15
|
+
* them; the fitting rule applies to the conversion output, not the input).
|
|
16
|
+
* Strict: a task file with unknown fields is malformed, not tolerated.
|
|
17
|
+
*/
|
|
18
|
+
export declare const CapturedTaskSchema: z.ZodObject<{
|
|
19
|
+
session: z.ZodObject<{
|
|
20
|
+
sessionId: z.ZodString;
|
|
21
|
+
capturedAt: z.ZodISODateTime;
|
|
22
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
23
|
+
user: "user";
|
|
24
|
+
"host-internal": "host-internal";
|
|
25
|
+
}>>;
|
|
26
|
+
parentSessionId: z.ZodOptional<z.ZodString>;
|
|
27
|
+
}, z.core.$strict>;
|
|
28
|
+
task: z.ZodObject<{
|
|
29
|
+
summary: z.ZodString;
|
|
30
|
+
distributionTags: z.ZodArray<z.ZodString>;
|
|
31
|
+
repositorySlug: z.ZodOptional<z.ZodString>;
|
|
32
|
+
baseCommit: z.ZodOptional<z.ZodString>;
|
|
33
|
+
createdAt: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
instanceId: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}, z.core.$strict>;
|
|
36
|
+
environment: z.ZodObject<{
|
|
37
|
+
harness: z.ZodObject<{
|
|
38
|
+
name: z.ZodString;
|
|
39
|
+
version: z.ZodString;
|
|
40
|
+
}, z.core.$strict>;
|
|
41
|
+
model: z.ZodString;
|
|
42
|
+
tools: z.ZodArray<z.ZodString>;
|
|
43
|
+
skillsLoadout: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
44
|
+
generatorModel: z.ZodOptional<z.ZodObject<{
|
|
45
|
+
id: z.ZodString;
|
|
46
|
+
provider: z.ZodOptional<z.ZodString>;
|
|
47
|
+
openWeights: z.ZodOptional<z.ZodBoolean>;
|
|
48
|
+
source: z.ZodEnum<{
|
|
49
|
+
stream: "stream";
|
|
50
|
+
config: "config";
|
|
51
|
+
}>;
|
|
52
|
+
}, z.core.$strict>>;
|
|
53
|
+
distributionClass: z.ZodOptional<z.ZodEnum<{
|
|
54
|
+
unknown: "unknown";
|
|
55
|
+
open: "open";
|
|
56
|
+
"restricted-tos": "restricted-tos";
|
|
57
|
+
}>>;
|
|
58
|
+
verifier: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
59
|
+
type: z.ZodLiteral<"f2p-p2p">;
|
|
60
|
+
failToPass: z.ZodArray<z.ZodString>;
|
|
61
|
+
passToPass: z.ZodArray<z.ZodString>;
|
|
62
|
+
evalSemanticsVersion: z.ZodString;
|
|
63
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
64
|
+
type: z.ZodEnum<{
|
|
65
|
+
command: "command";
|
|
66
|
+
none: "none";
|
|
67
|
+
}>;
|
|
68
|
+
failToPass: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
69
|
+
passToPass: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
70
|
+
evalSemanticsVersion: z.ZodOptional<z.ZodString>;
|
|
71
|
+
}, z.core.$strict>], "type">>;
|
|
72
|
+
}, z.core.$strict>;
|
|
73
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
74
|
+
spanId: z.ZodString;
|
|
75
|
+
parentSpanId: z.ZodNullable<z.ZodString>;
|
|
76
|
+
name: z.ZodString;
|
|
77
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
78
|
+
"jinn.agent_turn": "jinn.agent_turn";
|
|
79
|
+
"jinn.tool_call": "jinn.tool_call";
|
|
80
|
+
}>>;
|
|
81
|
+
startTimeUnixNano: z.ZodString;
|
|
82
|
+
endTimeUnixNano: z.ZodString;
|
|
83
|
+
attributes: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
84
|
+
redactedKeys: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
85
|
+
events: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
86
|
+
timeUnixNano: z.ZodString;
|
|
87
|
+
name: z.ZodString;
|
|
88
|
+
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
89
|
+
}, z.core.$strict>>>;
|
|
90
|
+
status: z.ZodOptional<z.ZodObject<{
|
|
91
|
+
code: z.ZodEnum<{
|
|
92
|
+
UNSET: "UNSET";
|
|
93
|
+
OK: "OK";
|
|
94
|
+
ERROR: "ERROR";
|
|
95
|
+
}>;
|
|
96
|
+
message: z.ZodOptional<z.ZodString>;
|
|
97
|
+
}, z.core.$strict>>;
|
|
98
|
+
}, z.core.$strict>>;
|
|
99
|
+
outcome: z.ZodObject<{
|
|
100
|
+
status: z.ZodEnum<{
|
|
101
|
+
completed: "completed";
|
|
102
|
+
failed: "failed";
|
|
103
|
+
abandoned: "abandoned";
|
|
104
|
+
}>;
|
|
105
|
+
verifiabilityTier: z.ZodEnum<{
|
|
106
|
+
"user-accepted": "user-accepted";
|
|
107
|
+
"tests-passed": "tests-passed";
|
|
108
|
+
"evaluator-verified": "evaluator-verified";
|
|
109
|
+
}>;
|
|
110
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
111
|
+
}, z.core.$strict>;
|
|
112
|
+
cost: z.ZodObject<{
|
|
113
|
+
durationMs: z.ZodNumber;
|
|
114
|
+
tokens: z.ZodOptional<z.ZodObject<{
|
|
115
|
+
input: z.ZodNumber;
|
|
116
|
+
output: z.ZodNumber;
|
|
117
|
+
}, z.core.$strict>>;
|
|
118
|
+
usdEstimate: z.ZodOptional<z.ZodString>;
|
|
119
|
+
}, z.core.$strict>;
|
|
120
|
+
attemptGroup: z.ZodOptional<z.ZodObject<{
|
|
121
|
+
groupId: z.ZodString;
|
|
122
|
+
attemptId: z.ZodString;
|
|
123
|
+
relatedAttemptRefs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
124
|
+
groupSize: z.ZodOptional<z.ZodNumber>;
|
|
125
|
+
nPass: z.ZodOptional<z.ZodNumber>;
|
|
126
|
+
nFail: z.ZodOptional<z.ZodNumber>;
|
|
127
|
+
}, z.core.$strict>>;
|
|
128
|
+
lineage: z.ZodOptional<z.ZodObject<{
|
|
129
|
+
episodeId: z.ZodString;
|
|
130
|
+
mintRef: z.ZodOptional<z.ZodString>;
|
|
131
|
+
}, z.core.$strict>>;
|
|
132
|
+
provenance: z.ZodDefault<z.ZodEnum<{
|
|
133
|
+
contributed: "contributed";
|
|
134
|
+
imported: "imported";
|
|
135
|
+
"derived-from-history": "derived-from-history";
|
|
136
|
+
}>>;
|
|
137
|
+
}, z.core.$strict>;
|
|
138
|
+
export type CapturedTask = z.infer<typeof CapturedTaskSchema>;
|
|
139
|
+
/** Parse an untrusted value (e.g. a task file) as a CapturedTask; throws ZodError. */
|
|
140
|
+
export declare function parseCapturedTask(input: unknown): CapturedTask;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captured-task schema — the raw, pre-scrub input to the harness capture path.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from the former client harness layer in C2 (#1833):
|
|
5
|
+
* the parse half of capture.ts has no scrub / `client/src` dependency (only
|
|
6
|
+
* zod + the two envelope enums), so it moved into `@jinn-network/core`.
|
|
7
|
+
* C5 subsequently moved the scrub implementation alongside it while leaving
|
|
8
|
+
* capture orchestration in the layer.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { EvidenceProvenanceSchema, OutcomeStatusSchema, VerifiabilityTierSchema, } from './envelope.js';
|
|
12
|
+
/** Unix-nanosecond timestamp string (OTel span convention). */
|
|
13
|
+
const UnixNanoSchema = z.string().regex(/^\d+$/, 'unix-nanosecond digit string');
|
|
14
|
+
const F2pP2pVerifierSchema = z.strictObject({
|
|
15
|
+
type: z.literal('f2p-p2p'),
|
|
16
|
+
failToPass: z.array(z.string().min(1)),
|
|
17
|
+
passToPass: z.array(z.string().min(1)),
|
|
18
|
+
evalSemanticsVersion: z.string().min(1),
|
|
19
|
+
});
|
|
20
|
+
const OtherVerifierSchema = z.strictObject({
|
|
21
|
+
type: z.enum(['command', 'none']),
|
|
22
|
+
failToPass: z.array(z.string().min(1)).default([]),
|
|
23
|
+
passToPass: z.array(z.string().min(1)).default([]),
|
|
24
|
+
evalSemanticsVersion: z.string().min(1).optional(),
|
|
25
|
+
});
|
|
26
|
+
const CapturedVerifierSchema = z.discriminatedUnion('type', [
|
|
27
|
+
F2pP2pVerifierSchema,
|
|
28
|
+
OtherVerifierSchema,
|
|
29
|
+
]);
|
|
30
|
+
const CapturedStepEventSchema = z.strictObject({
|
|
31
|
+
timeUnixNano: UnixNanoSchema,
|
|
32
|
+
name: z.string().min(1),
|
|
33
|
+
attributes: z.record(z.string(), z.unknown()).optional(),
|
|
34
|
+
});
|
|
35
|
+
const CapturedStepStatusSchema = z.strictObject({
|
|
36
|
+
code: z.enum(['UNSET', 'OK', 'ERROR']),
|
|
37
|
+
message: z.string().min(1).optional(),
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* A captured task — the raw, pre-scrub input to `capture()`. Mirrors the
|
|
41
|
+
* envelope shape minus `consent` (which does not exist pre-consent) with
|
|
42
|
+
* UNSCRUBBED step attributes and no size caps (raw captures routinely exceed
|
|
43
|
+
* them; the fitting rule applies to the conversion output, not the input).
|
|
44
|
+
* Strict: a task file with unknown fields is malformed, not tolerated.
|
|
45
|
+
*/
|
|
46
|
+
export const CapturedTaskSchema = z.strictObject({
|
|
47
|
+
session: z.strictObject({
|
|
48
|
+
sessionId: z.string().min(1).max(128),
|
|
49
|
+
capturedAt: z.iso.datetime(),
|
|
50
|
+
kind: z.enum(['user', 'host-internal']).optional(),
|
|
51
|
+
parentSessionId: z.string().min(1).max(128).optional(),
|
|
52
|
+
}),
|
|
53
|
+
task: z.strictObject({
|
|
54
|
+
summary: z.string().min(1),
|
|
55
|
+
distributionTags: z.array(z.string().min(1)).min(1),
|
|
56
|
+
repositorySlug: z.string().min(1).optional(),
|
|
57
|
+
baseCommit: z.string().min(1).optional(),
|
|
58
|
+
createdAt: z.number().int().nonnegative().optional(),
|
|
59
|
+
instanceId: z.string().min(1).optional(),
|
|
60
|
+
}),
|
|
61
|
+
environment: z.strictObject({
|
|
62
|
+
harness: z.strictObject({
|
|
63
|
+
name: z.string().min(1),
|
|
64
|
+
version: z.string().min(1),
|
|
65
|
+
}),
|
|
66
|
+
model: z.string().min(1),
|
|
67
|
+
tools: z.array(z.string().min(1)),
|
|
68
|
+
skillsLoadout: z.array(z.string().min(1)).optional(),
|
|
69
|
+
generatorModel: z.strictObject({
|
|
70
|
+
id: z.string().min(1),
|
|
71
|
+
provider: z.string().min(1).optional(),
|
|
72
|
+
openWeights: z.boolean().optional(),
|
|
73
|
+
source: z.enum(['stream', 'config']),
|
|
74
|
+
}).optional(),
|
|
75
|
+
distributionClass: z.enum(['open', 'restricted-tos', 'unknown']).optional(),
|
|
76
|
+
verifier: CapturedVerifierSchema.optional(),
|
|
77
|
+
}),
|
|
78
|
+
steps: z.array(z.strictObject({
|
|
79
|
+
spanId: z.string().min(1),
|
|
80
|
+
parentSpanId: z.string().min(1).nullable(),
|
|
81
|
+
name: z.string().min(1),
|
|
82
|
+
kind: z.enum(['jinn.agent_turn', 'jinn.tool_call']).optional(),
|
|
83
|
+
startTimeUnixNano: UnixNanoSchema,
|
|
84
|
+
endTimeUnixNano: UnixNanoSchema,
|
|
85
|
+
attributes: z.record(z.string(), z.unknown()),
|
|
86
|
+
/** Keys already redacted at ingest, if the capture recorded any. */
|
|
87
|
+
redactedKeys: z.array(z.string().min(1)).default([]),
|
|
88
|
+
/** Optional canonical OTLP observations retained by richer transcript parsers. */
|
|
89
|
+
events: z.array(CapturedStepEventSchema).optional(),
|
|
90
|
+
status: CapturedStepStatusSchema.optional(),
|
|
91
|
+
})).min(1),
|
|
92
|
+
outcome: z.strictObject({
|
|
93
|
+
status: OutcomeStatusSchema,
|
|
94
|
+
verifiabilityTier: VerifiabilityTierSchema,
|
|
95
|
+
summary: z.string().min(1).optional(),
|
|
96
|
+
}),
|
|
97
|
+
cost: z.strictObject({
|
|
98
|
+
durationMs: z.number().int().nonnegative(),
|
|
99
|
+
tokens: z.strictObject({
|
|
100
|
+
input: z.number().int().nonnegative(),
|
|
101
|
+
output: z.number().int().nonnegative(),
|
|
102
|
+
}).optional(),
|
|
103
|
+
usdEstimate: z.string().regex(/^\d+(\.\d+)?$/).optional(),
|
|
104
|
+
}),
|
|
105
|
+
attemptGroup: z.strictObject({
|
|
106
|
+
groupId: z.string().min(1),
|
|
107
|
+
attemptId: z.string().min(1),
|
|
108
|
+
relatedAttemptRefs: z.array(z.string().min(1)).default([]),
|
|
109
|
+
groupSize: z.number().int().positive().optional(),
|
|
110
|
+
nPass: z.number().int().nonnegative().optional(),
|
|
111
|
+
nFail: z.number().int().nonnegative().optional(),
|
|
112
|
+
}).optional(),
|
|
113
|
+
lineage: z.strictObject({
|
|
114
|
+
episodeId: z.string().min(1),
|
|
115
|
+
mintRef: z.string().min(1).optional(),
|
|
116
|
+
}).optional(),
|
|
117
|
+
provenance: EvidenceProvenanceSchema.default('contributed'),
|
|
118
|
+
});
|
|
119
|
+
/** Parse an untrusted value (e.g. a task file) as a CapturedTask; throws ZodError. */
|
|
120
|
+
export function parseCapturedTask(input) {
|
|
121
|
+
return CapturedTaskSchema.parse(input);
|
|
122
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type ContributionCandidateV1, type EpisodeV1, type ContributionLocalState, type ContributionPublicationState } from '@jinn-network/plugin';
|
|
2
|
+
export declare const CONTRIBUTION_STORE_SCHEMA_VERSION: "jinn.contribution-store.v3";
|
|
3
|
+
export declare const CONTRIBUTION_STORE_FILE: "mineable-traces.json";
|
|
4
|
+
export declare const CONTRIBUTION_PUBLICATION_DISABLED_FILE: "publication-disabled";
|
|
5
|
+
export declare const CONTRIBUTION_PUBLICATION_SCHEMA_VERSION: "jinn.contribution-publication.v1";
|
|
6
|
+
export declare const DEFAULT_CONTRIBUTION_STATE_DIR: string;
|
|
7
|
+
export declare function resolveContributionStateDir(env?: {
|
|
8
|
+
JINN_MINEABLE_STATE_DIR?: string;
|
|
9
|
+
}): string;
|
|
10
|
+
export interface ContributionLocalMetadata {
|
|
11
|
+
/** Compatibility-only task kind; never included in an outbound projection. */
|
|
12
|
+
kind?: 'solvernet-execution' | 'harness-session';
|
|
13
|
+
/** Compatibility-only source task reference for second-generation guards. */
|
|
14
|
+
sourceInstanceId?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ContributionStoreRecord {
|
|
17
|
+
recordId: string;
|
|
18
|
+
localState: ContributionLocalState;
|
|
19
|
+
publicationState: ContributionPublicationState;
|
|
20
|
+
mintRef?: string;
|
|
21
|
+
publicationRef?: string;
|
|
22
|
+
rejectionReason?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ContributionPublicationV1 {
|
|
25
|
+
schemaVersion: typeof CONTRIBUTION_PUBLICATION_SCHEMA_VERSION;
|
|
26
|
+
repositorySlug: string;
|
|
27
|
+
baseCommit: string;
|
|
28
|
+
mintRef: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ContributionStoreLockOptions {
|
|
31
|
+
retryDelayMs?: number;
|
|
32
|
+
maxRetries?: number;
|
|
33
|
+
staleAfterMs?: number;
|
|
34
|
+
}
|
|
35
|
+
export interface ContributionStoreOptions {
|
|
36
|
+
stateDir?: string;
|
|
37
|
+
filePath?: string;
|
|
38
|
+
lock?: ContributionStoreLockOptions;
|
|
39
|
+
publicationLock?: ContributionStoreLockOptions;
|
|
40
|
+
/** Lock-clock seam only. Candidate timestamps always come from the caller. */
|
|
41
|
+
nowMs?: () => number;
|
|
42
|
+
}
|
|
43
|
+
export interface ContributionStoreRecordOptions {
|
|
44
|
+
publicationState?: 'vetoed';
|
|
45
|
+
}
|
|
46
|
+
export interface ContributionStoreReferenceOptions extends ContributionStoreRecordOptions {
|
|
47
|
+
/** Transition input only; never serialized in the reference store. */
|
|
48
|
+
publishMinedTasksConsent?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Cacheless, cross-process-safe contribution store. Every mutation acquires a
|
|
52
|
+
* mkdir-based lock and performs a fresh read-modify-atomic-rename cycle.
|
|
53
|
+
*/
|
|
54
|
+
export declare class ContributionStore {
|
|
55
|
+
readonly filePath: string;
|
|
56
|
+
private readonly lockPath;
|
|
57
|
+
private readonly publicationLockPath;
|
|
58
|
+
private readonly publicationDisabledPath;
|
|
59
|
+
private readonly lock;
|
|
60
|
+
private readonly publicationLock;
|
|
61
|
+
private readonly nowMs;
|
|
62
|
+
constructor(options: ContributionStoreOptions);
|
|
63
|
+
private tryRecoverStaleLock;
|
|
64
|
+
private ownerProcessAlive;
|
|
65
|
+
private recoveryOwnerName;
|
|
66
|
+
private recoveryOwnerMetadata;
|
|
67
|
+
private acquireRecoveryGuard;
|
|
68
|
+
private acquireLockAt;
|
|
69
|
+
private withLockAt;
|
|
70
|
+
private withLock;
|
|
71
|
+
private withPublicationLock;
|
|
72
|
+
private writeAtomic;
|
|
73
|
+
private preserveMigrationBackup;
|
|
74
|
+
private loadUnlocked;
|
|
75
|
+
private mutate;
|
|
76
|
+
private publicationDisabledUnlocked;
|
|
77
|
+
record(candidateInput: ContributionCandidateV1, _localMetadata?: ContributionLocalMetadata, options?: ContributionStoreRecordOptions): Promise<ContributionStoreRecord>;
|
|
78
|
+
recordReference(episodeId: string, options?: ContributionStoreReferenceOptions): Promise<ContributionStoreRecord>;
|
|
79
|
+
get(recordId: string): Promise<ContributionStoreRecord | undefined>;
|
|
80
|
+
list(): Promise<ContributionStoreRecord[]>;
|
|
81
|
+
listRecorded(): Promise<ContributionStoreRecord[]>;
|
|
82
|
+
authorize(recordId: string, acknowledgedAt: string): Promise<ContributionStoreRecord>;
|
|
83
|
+
markMinted(recordId: string, mintRef?: string): Promise<ContributionStoreRecord>;
|
|
84
|
+
markRejected(recordId: string, reason?: string): Promise<ContributionStoreRecord>;
|
|
85
|
+
veto(recordId: string): Promise<ContributionStoreRecord>;
|
|
86
|
+
disableUnpublished(): Promise<string[]>;
|
|
87
|
+
enablePublication(): Promise<void>;
|
|
88
|
+
publishAuthorized<T>(recordId: string, operation: () => Promise<{
|
|
89
|
+
value: T;
|
|
90
|
+
mintRef: string;
|
|
91
|
+
publicationRef: string;
|
|
92
|
+
}>): Promise<T>;
|
|
93
|
+
markPublished(recordId: string, publicationRef: string): Promise<ContributionStoreRecord>;
|
|
94
|
+
toOutboundProjection(record: ContributionStoreRecord, episodeInput: EpisodeV1): ContributionPublicationV1;
|
|
95
|
+
private requireRecord;
|
|
96
|
+
private throwPublishedImmutable;
|
|
97
|
+
}
|