@jinn-network/jinn-layer 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/adapters/contribution-adapter.d.ts +18 -0
- package/dist/adapters/contribution-adapter.js +134 -0
- package/dist/adapters/corpus-adapter.d.ts +12 -0
- package/dist/adapters/corpus-adapter.js +212 -0
- package/dist/adapters/index.d.ts +17 -0
- package/dist/adapters/index.js +17 -0
- package/dist/adapters/json-map-store.d.ts +4 -0
- package/dist/adapters/json-map-store.js +31 -0
- package/dist/adapters/local-learning-adapter.d.ts +25 -0
- package/dist/adapters/local-learning-adapter.js +49 -0
- package/dist/adapters/skills-adapter.d.ts +8 -0
- package/dist/adapters/skills-adapter.js +55 -0
- package/dist/admission-policy.d.ts +38 -0
- package/dist/admission-policy.js +17 -0
- package/dist/bin/jinn-distill-mcp.d.ts +2 -0
- package/dist/bin/jinn-distill-mcp.js +10 -0
- package/dist/bin/jinn-layer.d.ts +7 -0
- package/dist/bin/jinn-layer.js +15 -0
- package/dist/bridge-fetch-evidence.d.ts +102 -0
- package/dist/bridge-fetch-evidence.js +677 -0
- package/dist/bridge-verdict-source.d.ts +47 -0
- package/dist/bridge-verdict-source.js +216 -0
- package/dist/bridge.d.ts +247 -0
- package/dist/bridge.js +439 -0
- package/dist/capture.d.ts +98 -0
- package/dist/capture.js +617 -0
- package/dist/cli.d.ts +148 -0
- package/dist/cli.js +2221 -0
- package/dist/cluster-selection.d.ts +34 -0
- package/dist/cluster-selection.js +135 -0
- package/dist/cluster.d.ts +89 -0
- package/dist/cluster.js +142 -0
- package/dist/consume.d.ts +139 -0
- package/dist/consume.js +280 -0
- package/dist/corpus-probes.d.ts +61 -0
- package/dist/corpus-probes.js +120 -0
- package/dist/corpus-store.d.ts +16 -0
- package/dist/corpus-store.js +101 -0
- package/dist/distill-captures.d.ts +56 -0
- package/dist/distill-captures.js +283 -0
- package/dist/distill-feedback.d.ts +20 -0
- package/dist/distill-feedback.js +30 -0
- package/dist/distill-llm.d.ts +138 -0
- package/dist/distill-llm.js +438 -0
- package/dist/distill-mcp-server.d.ts +30 -0
- package/dist/distill-mcp-server.js +281 -0
- package/dist/distill-mode.d.ts +62 -0
- package/dist/distill-mode.js +107 -0
- package/dist/distill-progress.d.ts +78 -0
- package/dist/distill-progress.js +69 -0
- package/dist/distill-prompt.d.ts +34 -0
- package/dist/distill-prompt.js +85 -0
- package/dist/distill-render.d.ts +123 -0
- package/dist/distill-render.js +303 -0
- package/dist/distill-runs.d.ts +28 -0
- package/dist/distill-runs.js +39 -0
- package/dist/distill-traces.d.ts +67 -0
- package/dist/distill-traces.js +211 -0
- package/dist/distill.d.ts +180 -0
- package/dist/distill.js +337 -0
- package/dist/distiller.d.ts +118 -0
- package/dist/distiller.js +142 -0
- package/dist/envelope.d.ts +9 -0
- package/dist/envelope.js +9 -0
- package/dist/eval-prep.d.ts +129 -0
- package/dist/eval-prep.js +523 -0
- package/dist/execution-publish.d.ts +62 -0
- package/dist/execution-publish.js +72 -0
- package/dist/gate.d.ts +39 -0
- package/dist/gate.js +106 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +50 -0
- package/dist/ipfs-cid.d.ts +18 -0
- package/dist/ipfs-cid.js +149 -0
- package/dist/layer-default.d.ts +3 -0
- package/dist/layer-default.js +10 -0
- package/dist/ledger.d.ts +62 -0
- package/dist/ledger.js +104 -0
- package/dist/measurement.d.ts +90 -0
- package/dist/measurement.js +134 -0
- package/dist/path-safety.d.ts +19 -0
- package/dist/path-safety.js +303 -0
- package/dist/pipeline.d.ts +94 -0
- package/dist/pipeline.js +124 -0
- package/dist/plugin-wiring.d.ts +4 -0
- package/dist/plugin-wiring.js +54 -0
- package/dist/preview.d.ts +31 -0
- package/dist/preview.js +28 -0
- package/dist/process-contract.d.ts +303 -0
- package/dist/process-contract.js +118 -0
- package/dist/publish-skill.d.ts +86 -0
- package/dist/publish-skill.js +116 -0
- package/dist/publish.d.ts +294 -0
- package/dist/publish.js +1090 -0
- package/dist/scripts/scan-skills-registry.d.ts +24 -0
- package/dist/scripts/scan-skills-registry.js +207 -0
- package/dist/seed-import/curated-batch.d.ts +36 -0
- package/dist/seed-import/curated-batch.js +103 -0
- package/dist/seed-import/episode-execute.d.ts +50 -0
- package/dist/seed-import/episode-execute.js +235 -0
- package/dist/seed-import/episode-fetch.d.ts +119 -0
- package/dist/seed-import/episode-fetch.js +137 -0
- package/dist/seed-import/episode-plan.d.ts +11 -0
- package/dist/seed-import/episode-plan.js +27 -0
- package/dist/seed-import/episode-report.d.ts +39 -0
- package/dist/seed-import/episode-report.js +36 -0
- package/dist/seed-import/execute.d.ts +61 -0
- package/dist/seed-import/execute.js +245 -0
- package/dist/seed-import/fetch.d.ts +62 -0
- package/dist/seed-import/fetch.js +82 -0
- package/dist/seed-import/licence.d.ts +17 -0
- package/dist/seed-import/licence.js +36 -0
- package/dist/seed-import/plan.d.ts +10 -0
- package/dist/seed-import/plan.js +21 -0
- package/dist/seed-import/report.d.ts +34 -0
- package/dist/seed-import/report.js +31 -0
- package/dist/seed-import/state.d.ts +72 -0
- package/dist/seed-import/state.js +120 -0
- package/dist/signal.d.ts +36 -0
- package/dist/signal.js +48 -0
- package/dist/signing.d.ts +8 -0
- package/dist/signing.js +21 -0
- package/dist/skill-package.d.ts +70 -0
- package/dist/skill-package.js +141 -0
- package/dist/skill.d.ts +21 -0
- package/dist/skill.js +77 -0
- package/dist/snapshot-transcript.d.ts +54 -0
- package/dist/snapshot-transcript.js +117 -0
- package/dist/three-arm-run.d.ts +27 -0
- package/dist/three-arm-run.js +41 -0
- package/package.json +60 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* system_snapshot extraction — donation unwrap + ustar read + transcript
|
|
3
|
+
* lookup (issue #1472, spec §8).
|
|
4
|
+
*
|
|
5
|
+
* The engine tars each solve's working dir into a `system_snapshot` artifact
|
|
6
|
+
* (hand-rolled POSIX ustar + gzip, `client/src/harnesses/engine/packaging.ts`
|
|
7
|
+
* `createWorkdirTarball`) and publishes it donation-wrapped
|
|
8
|
+
* (`jinn.artifact.donation.v1`: JSON with base64 `data`). Inside is the
|
|
9
|
+
* harness's raw stdout transcript (`.claude-code/stdout.jsonl`,
|
|
10
|
+
* `.codex-code/stdout.jsonl`) — the solve's actual reasoning, which
|
|
11
|
+
* `jinn.trajectory.v1` does NOT carry (2 artifact.emit spans only; #1473
|
|
12
|
+
* tracks fixing that at solve time).
|
|
13
|
+
*
|
|
14
|
+
* `unwrapDonation` mirrors the module-private `decodeDonationArtifact`
|
|
15
|
+
* (`@jinn-network/core/corpus-read`) and additionally verifies the decoded
|
|
16
|
+
* bytes hash to the declared sha256 (tamper check). The ustar reader mirrors
|
|
17
|
+
* the writer: regular files only, names ≤100 chars, no PAX/GNU extensions —
|
|
18
|
+
* a malformed header ends iteration rather than throwing. Decompression is
|
|
19
|
+
* bomb-guarded via zlib's `maxOutputLength`.
|
|
20
|
+
*/
|
|
21
|
+
import { createHash } from 'node:crypto';
|
|
22
|
+
import { gunzipSync } from 'node:zlib';
|
|
23
|
+
import { ClaudeCodeStreamJsonParser, CodexExecJsonParser, } from '@jinn-network/core/trajectory';
|
|
24
|
+
const DONATION_ENCODING = 'jinn.artifact.donation.v1';
|
|
25
|
+
/** Gzip-bomb guard: snapshots observed live are ≤ ~300 KB compressed. */
|
|
26
|
+
export const MAX_SNAPSHOT_DECOMPRESSED_BYTES = 32 * 1024 * 1024;
|
|
27
|
+
/** Transcript locations the learner adapters write under the workingDir. */
|
|
28
|
+
const TRANSCRIPT_PATHS = [
|
|
29
|
+
{ suffix: '.claude-code/stdout.jsonl', harness: 'claude-code' },
|
|
30
|
+
{ suffix: '.codex-code/stdout.jsonl', harness: 'codex' },
|
|
31
|
+
// .hermes-agent/stdout.log is a ~1KB plain-text log — no decision path; skipped.
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Decode a `jinn.artifact.donation.v1` wrapper to its raw bytes. Throws on a
|
|
35
|
+
* non-donation shape, a declared-sha mismatch against `expectedSha256`, or
|
|
36
|
+
* decoded bytes that do not hash to the declared sha (tamper check — parity
|
|
37
|
+
* plus-one with corpus/acquire.ts `decodeDonationArtifact`).
|
|
38
|
+
*/
|
|
39
|
+
export function unwrapDonation(raw, expectedSha256) {
|
|
40
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
41
|
+
throw new Error('donation artifact payload is not an object');
|
|
42
|
+
}
|
|
43
|
+
const record = raw;
|
|
44
|
+
if (record['schemaVersion'] !== DONATION_ENCODING || record['encoding'] !== DONATION_ENCODING) {
|
|
45
|
+
throw new Error('donation artifact payload has unexpected encoding');
|
|
46
|
+
}
|
|
47
|
+
if (record['sha256'] !== expectedSha256) {
|
|
48
|
+
throw new Error('donation artifact sha256 does not match requested artifact');
|
|
49
|
+
}
|
|
50
|
+
if (typeof record['data'] !== 'string') {
|
|
51
|
+
throw new Error('donation artifact payload is missing base64 data');
|
|
52
|
+
}
|
|
53
|
+
const bytes = Buffer.from(record['data'], 'base64');
|
|
54
|
+
const computed = createHash('sha256').update(bytes).digest('hex');
|
|
55
|
+
if (computed !== expectedSha256) {
|
|
56
|
+
throw new Error('donation artifact bytes do not hash to the declared sha256');
|
|
57
|
+
}
|
|
58
|
+
return bytes;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Gunzip (bomb-guarded) + read a POSIX ustar archive into entries. Regular
|
|
62
|
+
* files only; a malformed/truncated header or size field ends iteration
|
|
63
|
+
* (best-effort read of what is intact, never an infinite loop).
|
|
64
|
+
*/
|
|
65
|
+
export function untarGz(tarGz) {
|
|
66
|
+
const tar = gunzipSync(tarGz, { maxOutputLength: MAX_SNAPSHOT_DECOMPRESSED_BYTES });
|
|
67
|
+
const entries = [];
|
|
68
|
+
let off = 0;
|
|
69
|
+
while (off + 512 <= tar.length) {
|
|
70
|
+
const name = tar.subarray(off, off + 100).toString('utf8').replace(/\0.*$/, '');
|
|
71
|
+
if (!name)
|
|
72
|
+
break; // end-of-archive zero block
|
|
73
|
+
const sizeField = tar
|
|
74
|
+
.subarray(off + 124, off + 136)
|
|
75
|
+
.toString('utf8')
|
|
76
|
+
.replace(/\0.*$/, '')
|
|
77
|
+
.trim();
|
|
78
|
+
const size = parseInt(sizeField, 8);
|
|
79
|
+
if (!Number.isFinite(size) || size < 0)
|
|
80
|
+
break; // malformed header — stop
|
|
81
|
+
const typeflag = String.fromCharCode(tar[off + 156] ?? 48);
|
|
82
|
+
const bodyStart = off + 512;
|
|
83
|
+
const bodyEnd = bodyStart + size;
|
|
84
|
+
if (bodyEnd > tar.length)
|
|
85
|
+
break; // truncated body — stop
|
|
86
|
+
if (typeflag === '0' || typeflag === '\0') {
|
|
87
|
+
entries.push({ name, bytes: tar.subarray(bodyStart, bodyEnd) });
|
|
88
|
+
}
|
|
89
|
+
off = bodyStart + Math.ceil(size / 512) * 512;
|
|
90
|
+
}
|
|
91
|
+
return entries;
|
|
92
|
+
}
|
|
93
|
+
/** Locate the solve transcript among snapshot entries, or null if absent. */
|
|
94
|
+
export function findSolveTranscript(entries) {
|
|
95
|
+
for (const { suffix, harness } of TRANSCRIPT_PATHS) {
|
|
96
|
+
const entry = entries.find((e) => e.name === suffix || e.name.endsWith(`/${suffix}`));
|
|
97
|
+
if (entry)
|
|
98
|
+
return { harness, jsonl: entry.bytes.toString('utf8') };
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* End-to-end: donation wrapper JSON → the solve transcript, or null when the
|
|
104
|
+
* snapshot carries none (hermes, or transcript-less). Throws on unwrap /
|
|
105
|
+
* decompression failures — the caller treats any throw as "no enrichment".
|
|
106
|
+
*/
|
|
107
|
+
export function extractSnapshotTranscript(wrapper, expectedSha256) {
|
|
108
|
+
const bytes = unwrapDonation(wrapper, expectedSha256);
|
|
109
|
+
return findSolveTranscript(untarGz(bytes));
|
|
110
|
+
}
|
|
111
|
+
/** Parse snapshot stdout with the same canonical typed-span parser as the live path. */
|
|
112
|
+
export function parseSolveTranscript(transcript) {
|
|
113
|
+
const parser = transcript.harness === 'claude-code'
|
|
114
|
+
? new ClaudeCodeStreamJsonParser()
|
|
115
|
+
: new CodexExecJsonParser();
|
|
116
|
+
return parser.parseText(transcript.jsonl);
|
|
117
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three-arm measurement runner (spec/2026-07-06-distillation-v1.md §11).
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the §11 run: for each arm — seeds-only (control), raw-evidence
|
|
5
|
+
* (the D11 product baseline), distilled — run the held-out slate under that
|
|
6
|
+
* arm's pre-installed corpus snapshot, collect per-instance pass/fail + cost,
|
|
7
|
+
* then hand all three to `threeArmMeasurement` for the gate + pilot verdict.
|
|
8
|
+
*
|
|
9
|
+
* The per-arm RUN is an injected port (`runArm`). Its production implementation
|
|
10
|
+
* is the **capability-eval rig (#1416)** — pre-install a content-addressed corpus
|
|
11
|
+
* snapshot, run the swe-rebench-v2 slate under it, grade in Docker. That rig is a
|
|
12
|
+
* follow-on; keeping it a port means this orchestration is correct and tested now
|
|
13
|
+
* and the real runner drops in unchanged. Arms run **sequentially by default** to
|
|
14
|
+
* bound disk/inference; each is expensive.
|
|
15
|
+
*/
|
|
16
|
+
import { type ArmResult, type ThreeArmResult } from './measurement.js';
|
|
17
|
+
export type ArmName = 'seedsOnly' | 'rawEvidence' | 'distilled';
|
|
18
|
+
export interface ThreeArmRunDeps {
|
|
19
|
+
/** Run the held-out slate under an arm's pre-installed loadout → per-instance results. */
|
|
20
|
+
runArm: (arm: ArmName) => Promise<ArmResult[]>;
|
|
21
|
+
alpha?: number;
|
|
22
|
+
costMargin?: number;
|
|
23
|
+
/** Run arms concurrently (default false — arms are disk/inference-heavy, so serialize). */
|
|
24
|
+
parallel?: boolean;
|
|
25
|
+
log?: (msg: string) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare function runThreeArm(deps: ThreeArmRunDeps): Promise<ThreeArmResult>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three-arm measurement runner (spec/2026-07-06-distillation-v1.md §11).
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the §11 run: for each arm — seeds-only (control), raw-evidence
|
|
5
|
+
* (the D11 product baseline), distilled — run the held-out slate under that
|
|
6
|
+
* arm's pre-installed corpus snapshot, collect per-instance pass/fail + cost,
|
|
7
|
+
* then hand all three to `threeArmMeasurement` for the gate + pilot verdict.
|
|
8
|
+
*
|
|
9
|
+
* The per-arm RUN is an injected port (`runArm`). Its production implementation
|
|
10
|
+
* is the **capability-eval rig (#1416)** — pre-install a content-addressed corpus
|
|
11
|
+
* snapshot, run the swe-rebench-v2 slate under it, grade in Docker. That rig is a
|
|
12
|
+
* follow-on; keeping it a port means this orchestration is correct and tested now
|
|
13
|
+
* and the real runner drops in unchanged. Arms run **sequentially by default** to
|
|
14
|
+
* bound disk/inference; each is expensive.
|
|
15
|
+
*/
|
|
16
|
+
import { threeArmMeasurement } from './measurement.js';
|
|
17
|
+
const ARMS = ['seedsOnly', 'rawEvidence', 'distilled'];
|
|
18
|
+
export async function runThreeArm(deps) {
|
|
19
|
+
const log = deps.log ?? (() => { });
|
|
20
|
+
let seedsOnly;
|
|
21
|
+
let rawEvidence;
|
|
22
|
+
let distilled;
|
|
23
|
+
if (deps.parallel) {
|
|
24
|
+
log('running three arms concurrently');
|
|
25
|
+
[seedsOnly, rawEvidence, distilled] = await Promise.all(ARMS.map((a) => deps.runArm(a)));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
const out = {};
|
|
29
|
+
for (const arm of ARMS) {
|
|
30
|
+
log(`running arm: ${arm}`);
|
|
31
|
+
out[arm] = await deps.runArm(arm);
|
|
32
|
+
}
|
|
33
|
+
seedsOnly = out.seedsOnly;
|
|
34
|
+
rawEvidence = out.rawEvidence;
|
|
35
|
+
distilled = out.distilled;
|
|
36
|
+
}
|
|
37
|
+
return threeArmMeasurement({ seedsOnly, rawEvidence, distilled }, {
|
|
38
|
+
...(deps.alpha !== undefined ? { alpha: deps.alpha } : {}),
|
|
39
|
+
...(deps.costMargin !== undefined ? { costMargin: deps.costMargin } : {}),
|
|
40
|
+
});
|
|
41
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jinn-network/jinn-layer",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Standalone Jinn plugin process layer: host contract, local evidence, corpus reads, distillation, and seed import.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"packageManager": "yarn@4.13.0",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/Jinn-Network/mono.git",
|
|
11
|
+
"directory": "packages/layer"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=22"
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"jinn-distill-mcp": "./dist/bin/jinn-distill-mcp.js",
|
|
18
|
+
"jinn-layer": "./dist/bin/jinn-layer.js"
|
|
19
|
+
},
|
|
20
|
+
"main": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"files": [
|
|
23
|
+
"dist/"
|
|
24
|
+
],
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc -p tsconfig.json",
|
|
36
|
+
"pack:smoke": "node scripts/pack-smoke.mjs",
|
|
37
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
38
|
+
"test": "vitest run"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@jinn-network/core": "0.1.0",
|
|
42
|
+
"@jinn-network/plugin": "0.1.0",
|
|
43
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
44
|
+
"better-sqlite3": "^12.10.0",
|
|
45
|
+
"canonicalize": "^3.0.0",
|
|
46
|
+
"viem": "^2.0.0",
|
|
47
|
+
"yaml": "^2.8.4",
|
|
48
|
+
"zod": "^4.4.3"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
52
|
+
"@types/node": "^26.1.0",
|
|
53
|
+
"typescript": "^5.4.0",
|
|
54
|
+
"vitest": "^4.1.8"
|
|
55
|
+
},
|
|
56
|
+
"resolutions": {
|
|
57
|
+
"@jinn-network/core": "portal:../core",
|
|
58
|
+
"@jinn-network/plugin": "portal:../plugin"
|
|
59
|
+
}
|
|
60
|
+
}
|