@lanefoundry/source-prod-slice 0.0.0-canary-5535b4e
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/LICENSE +190 -0
- package/dist/audit-export.d.ts +58 -0
- package/dist/audit-export.d.ts.map +1 -0
- package/dist/audit-export.js +341 -0
- package/dist/audit-export.js.map +1 -0
- package/dist/canary-orchestrator.d.ts +150 -0
- package/dist/canary-orchestrator.d.ts.map +1 -0
- package/dist/canary-orchestrator.js +274 -0
- package/dist/canary-orchestrator.js.map +1 -0
- package/dist/compare-scores.d.ts +55 -0
- package/dist/compare-scores.d.ts.map +1 -0
- package/dist/compare-scores.js +131 -0
- package/dist/compare-scores.js.map +1 -0
- package/dist/freeze-slice.d.ts +63 -0
- package/dist/freeze-slice.d.ts.map +1 -0
- package/dist/freeze-slice.js +85 -0
- package/dist/freeze-slice.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/promotion-decision.d.ts +64 -0
- package/dist/promotion-decision.d.ts.map +1 -0
- package/dist/promotion-decision.js +105 -0
- package/dist/promotion-decision.js.map +1 -0
- package/dist/replay-batch.d.ts +71 -0
- package/dist/replay-batch.d.ts.map +1 -0
- package/dist/replay-batch.js +82 -0
- package/dist/replay-batch.js.map +1 -0
- package/dist/signed-report.d.ts +82 -0
- package/dist/signed-report.d.ts.map +1 -0
- package/dist/signed-report.js +104 -0
- package/dist/signed-report.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* signed-report.ts — Generate signed PromotionReport with trace IDs and candidate SHAs.
|
|
3
|
+
*
|
|
4
|
+
* Builds a complete PromotionReport from gate run artifacts and signs it
|
|
5
|
+
* using HMAC-SHA256 via the engine's signReport().
|
|
6
|
+
*
|
|
7
|
+
* @see docs/prd.md §5.1 — The gate
|
|
8
|
+
*/
|
|
9
|
+
import { signReport, canonicalizeReport } from '@lanefoundry/gatelane-engine';
|
|
10
|
+
import { shaOfCandidateRef } from '@lanefoundry/gatelane-sdk';
|
|
11
|
+
/**
|
|
12
|
+
* Build and sign a PromotionReport from gate run artifacts.
|
|
13
|
+
*
|
|
14
|
+
* This assembles all the pieces required by the PromotionReport type,
|
|
15
|
+
* computes the signature, and returns the complete signed report.
|
|
16
|
+
*/
|
|
17
|
+
export async function buildSignedReport(args) {
|
|
18
|
+
const { gateRunId, dataset, candidateShas, judgeShas, scorerCodeSha, baselineMetrics, candidateMetrics, judgeMatrix, policy, approver, signingKey, } = args;
|
|
19
|
+
// Validate required fields
|
|
20
|
+
if (!signingKey || signingKey.length < 16) {
|
|
21
|
+
throw new Error('signingKey must be >= 16 characters');
|
|
22
|
+
}
|
|
23
|
+
if (!gateRunId) {
|
|
24
|
+
throw new Error('gateRunId is required');
|
|
25
|
+
}
|
|
26
|
+
if (!dataset.content_hash) {
|
|
27
|
+
throw new Error('dataset must have content_hash');
|
|
28
|
+
}
|
|
29
|
+
// Build candidate_metrics in the shape expected by PromotionReport
|
|
30
|
+
const candidateMetricsForReport = {};
|
|
31
|
+
for (const [ref, metric] of Object.entries(candidateMetrics)) {
|
|
32
|
+
candidateMetricsForReport[ref] = {
|
|
33
|
+
aggregate_delta: metric.aggregate_delta,
|
|
34
|
+
cost_delta: metric.cost_delta,
|
|
35
|
+
latency_delta: metric.latency_delta,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// Build the report (without signature initially)
|
|
39
|
+
const report = {
|
|
40
|
+
id: `report-${gateRunId}`,
|
|
41
|
+
gate_run_id: gateRunId,
|
|
42
|
+
dataset_content_hash: dataset.content_hash,
|
|
43
|
+
dataset_version: dataset.version,
|
|
44
|
+
candidate_shas: candidateShas,
|
|
45
|
+
judge_shas: judgeShas,
|
|
46
|
+
scorer_code_sha: scorerCodeSha,
|
|
47
|
+
baseline_metrics: baselineMetrics,
|
|
48
|
+
candidate_metrics: candidateMetricsForReport,
|
|
49
|
+
judge_matrix: judgeMatrix,
|
|
50
|
+
policy,
|
|
51
|
+
approver,
|
|
52
|
+
timestamp: new Date().toISOString(),
|
|
53
|
+
signature: '', // placeholder; will be filled after signing
|
|
54
|
+
};
|
|
55
|
+
// Sign the report
|
|
56
|
+
const signature = await signReport(report, signingKey);
|
|
57
|
+
// Return signed report
|
|
58
|
+
const signedReport = {
|
|
59
|
+
...report,
|
|
60
|
+
signature,
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
report: signedReport,
|
|
64
|
+
canonicalJson: canonicalizeReport(signedReport),
|
|
65
|
+
signature,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Verify a PromotionReport's signature.
|
|
70
|
+
* Returns true if the signature matches the canonical JSON.
|
|
71
|
+
*/
|
|
72
|
+
export async function verifySignedReport(report, signingKey) {
|
|
73
|
+
const { verifyReport } = await import('@lanefoundry/gatelane-engine/sign');
|
|
74
|
+
return verifyReport(report, signingKey);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Generate candidate SHAs from source references.
|
|
78
|
+
* In production, these would come from git commit SHAs or container image digests.
|
|
79
|
+
*/
|
|
80
|
+
export async function generateCandidateShas(candidates) {
|
|
81
|
+
const shas = {};
|
|
82
|
+
for (const { ref, sourceRef } of candidates) {
|
|
83
|
+
shas[ref] = await shaOfCandidateRef(sourceRef);
|
|
84
|
+
}
|
|
85
|
+
return shas;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Generate judge SHAs from judge references.
|
|
89
|
+
*/
|
|
90
|
+
export async function generateJudgeShas(judges) {
|
|
91
|
+
const shas = {};
|
|
92
|
+
for (const { ref, model, version } of judges) {
|
|
93
|
+
const versioned = version ? `${model}@${version}` : model;
|
|
94
|
+
shas[ref] = await shaOfCandidateRef(versioned);
|
|
95
|
+
}
|
|
96
|
+
return shas;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Export a PromotionReport as canonical JSON for audit logs.
|
|
100
|
+
*/
|
|
101
|
+
export function exportReportForAudit(report) {
|
|
102
|
+
return canonicalizeReport(report);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=signed-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signed-report.js","sourceRoot":"","sources":["../src/signed-report.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lanefoundry/source-prod-slice",
|
|
3
|
+
"version": "0.0.0-canary-5535b4e",
|
|
4
|
+
"description": "Production slice tooling — freeze, replay, compare, promote, audit.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/lanefoundry/gatelane.git",
|
|
9
|
+
"directory": "packages/source-prod-slice"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/lanefoundry/gatelane/tree/main/packages/source-prod-slice",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./freeze-slice": {
|
|
21
|
+
"types": "./dist/freeze-slice.d.ts",
|
|
22
|
+
"import": "./dist/freeze-slice.js"
|
|
23
|
+
},
|
|
24
|
+
"./replay-batch": {
|
|
25
|
+
"types": "./dist/replay-batch.d.ts",
|
|
26
|
+
"import": "./dist/replay-batch.js"
|
|
27
|
+
},
|
|
28
|
+
"./compare-scores": {
|
|
29
|
+
"types": "./dist/compare-scores.d.ts",
|
|
30
|
+
"import": "./dist/compare-scores.js"
|
|
31
|
+
},
|
|
32
|
+
"./promotion-decision": {
|
|
33
|
+
"types": "./dist/promotion-decision.d.ts",
|
|
34
|
+
"import": "./dist/promotion-decision.js"
|
|
35
|
+
},
|
|
36
|
+
"./signed-report": {
|
|
37
|
+
"types": "./dist/signed-report.d.ts",
|
|
38
|
+
"import": "./dist/signed-report.js"
|
|
39
|
+
},
|
|
40
|
+
"./canary-orchestrator": {
|
|
41
|
+
"types": "./dist/canary-orchestrator.d.ts",
|
|
42
|
+
"import": "./dist/canary-orchestrator.js"
|
|
43
|
+
},
|
|
44
|
+
"./audit-export": {
|
|
45
|
+
"types": "./dist/audit-export.d.ts",
|
|
46
|
+
"import": "./dist/audit-export.js"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"dist"
|
|
51
|
+
],
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@lanefoundry/gatelane-sdk": "0.0.0-canary-5535b4e",
|
|
57
|
+
"@lanefoundry/gatelane-engine": "0.0.0-canary-5535b4e"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"typescript": "^5.5.4",
|
|
61
|
+
"vitest": "^2.0.5"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "tsc -p tsconfig.json",
|
|
65
|
+
"test": "vitest run"
|
|
66
|
+
}
|
|
67
|
+
}
|