@oscharko-dev/keiko-evidence 0.2.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/.tsbuildinfo +1 -0
- package/dist/aggregate.d.ts +4 -0
- package/dist/aggregate.d.ts.map +1 -0
- package/dist/aggregate.js +21 -0
- package/dist/build.d.ts +3 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +227 -0
- package/dist/connected-context-evidence.d.ts +47 -0
- package/dist/connected-context-evidence.d.ts.map +1 -0
- package/dist/connected-context-evidence.js +197 -0
- package/dist/errors.d.ts +3 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +4 -0
- package/dist/index-api.d.ts +15 -0
- package/dist/index-api.d.ts.map +1 -0
- package/dist/index-api.js +136 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/persist.d.ts +9 -0
- package/dist/persist.d.ts.map +1 -0
- package/dist/persist.js +40 -0
- package/dist/promptEnhancement/index.d.ts +7 -0
- package/dist/promptEnhancement/index.d.ts.map +1 -0
- package/dist/promptEnhancement/index.js +10 -0
- package/dist/promptEnhancement/manifestSchema.d.ts +71 -0
- package/dist/promptEnhancement/manifestSchema.d.ts.map +1 -0
- package/dist/promptEnhancement/manifestSchema.js +307 -0
- package/dist/promptEnhancement/redaction.d.ts +17 -0
- package/dist/promptEnhancement/redaction.d.ts.map +1 -0
- package/dist/promptEnhancement/redaction.js +66 -0
- package/dist/promptEnhancement/store.d.ts +64 -0
- package/dist/promptEnhancement/store.d.ts.map +1 -0
- package/dist/promptEnhancement/store.js +409 -0
- package/dist/qualityIntelligence/candidatesArtifact.d.ts +74 -0
- package/dist/qualityIntelligence/candidatesArtifact.d.ts.map +1 -0
- package/dist/qualityIntelligence/candidatesArtifact.js +258 -0
- package/dist/qualityIntelligence/companionStore.d.ts +37 -0
- package/dist/qualityIntelligence/companionStore.d.ts.map +1 -0
- package/dist/qualityIntelligence/companionStore.js +158 -0
- package/dist/qualityIntelligence/figmaSnapshot/schema.d.ts +123 -0
- package/dist/qualityIntelligence/figmaSnapshot/schema.d.ts.map +1 -0
- package/dist/qualityIntelligence/figmaSnapshot/schema.js +163 -0
- package/dist/qualityIntelligence/figmaSnapshot/store.d.ts +144 -0
- package/dist/qualityIntelligence/figmaSnapshot/store.d.ts.map +1 -0
- package/dist/qualityIntelligence/figmaSnapshot/store.js +898 -0
- package/dist/qualityIntelligence/index.d.ts +18 -0
- package/dist/qualityIntelligence/index.d.ts.map +1 -0
- package/dist/qualityIntelligence/index.js +21 -0
- package/dist/qualityIntelligence/manifestSchema.d.ts +154 -0
- package/dist/qualityIntelligence/manifestSchema.d.ts.map +1 -0
- package/dist/qualityIntelligence/manifestSchema.js +70 -0
- package/dist/qualityIntelligence/redaction.d.ts +10 -0
- package/dist/qualityIntelligence/redaction.d.ts.map +1 -0
- package/dist/qualityIntelligence/redaction.js +103 -0
- package/dist/qualityIntelligence/retention.d.ts +71 -0
- package/dist/qualityIntelligence/retention.d.ts.map +1 -0
- package/dist/qualityIntelligence/retention.js +287 -0
- package/dist/qualityIntelligence/retentionPolicy.d.ts +10 -0
- package/dist/qualityIntelligence/retentionPolicy.d.ts.map +1 -0
- package/dist/qualityIntelligence/retentionPolicy.js +38 -0
- package/dist/qualityIntelligence/store.d.ts +95 -0
- package/dist/qualityIntelligence/store.d.ts.map +1 -0
- package/dist/qualityIntelligence/store.js +483 -0
- package/dist/redaction.d.ts +2 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +4 -0
- package/dist/report.d.ts +17 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +50 -0
- package/dist/retention.d.ts +4 -0
- package/dist/retention.d.ts.map +1 -0
- package/dist/retention.js +95 -0
- package/dist/runid.d.ts +2 -0
- package/dist/runid.d.ts.map +1 -0
- package/dist/runid.js +4 -0
- package/dist/side-file.d.ts +9 -0
- package/dist/side-file.d.ts.map +1 -0
- package/dist/side-file.js +102 -0
- package/dist/store.d.ts +8 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +332 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +1 -0
- package/dist/workflow-evidence.d.ts +36 -0
- package/dist/workflow-evidence.d.ts.map +1 -0
- package/dist/workflow-evidence.js +158 -0
- package/package.json +32 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Shared workflow→EvidenceManifest mapping (ADR-0010 + ADR-0011 AC5 + ADR-0012 D9/C2). This is the
|
|
2
|
+
// PURE, surface-agnostic core that folds a terminated workflow run (its typed report + buffered
|
|
3
|
+
// events) into a redacted, versioned EvidenceManifest and writes it through the #10 EvidenceStore.
|
|
4
|
+
//
|
|
5
|
+
// Both the UI BFF and the evaluation harness build the manifest from this shared
|
|
6
|
+
// implementation. Gateway lookups (the model cost class) are accepted through the
|
|
7
|
+
// injected `EvidencePersistContext.costClassResolver` port rather than imported from
|
|
8
|
+
// the gateway capability registry. It defines its own narrow `WorkflowRunKind` /
|
|
9
|
+
// `WorkflowTerminalStatus` so it never depends on UI-local types.
|
|
10
|
+
//
|
|
11
|
+
import { buildEvidenceReport } from "./report.js";
|
|
12
|
+
import { createAuditRedactor, deepRedactStrings } from "./redaction.js";
|
|
13
|
+
import { EVIDENCE_SCHEMA_VERSION } from "./types.js";
|
|
14
|
+
import { HARNESS_VERSION, } from "@oscharko-dev/keiko-contracts";
|
|
15
|
+
const KIND_TO_TASK_TYPE = {
|
|
16
|
+
"unit-tests": "generate-unit-tests",
|
|
17
|
+
"bug-investigation": "investigate-bug",
|
|
18
|
+
};
|
|
19
|
+
// Folds the buffered `workflow:model:call:completed` events into usage totals. The workflow event
|
|
20
|
+
// carries token/latency fields at the TOP level (not under `usage` like the harness event), so this
|
|
21
|
+
// sums the four dimensions directly rather than reusing the audit `aggregateUsage` fold.
|
|
22
|
+
export function foldWorkflowUsage(events) {
|
|
23
|
+
let promptTokens = 0;
|
|
24
|
+
let completionTokens = 0;
|
|
25
|
+
let requestCount = 0;
|
|
26
|
+
let totalLatencyMs = 0;
|
|
27
|
+
for (const event of events) {
|
|
28
|
+
if (event.type !== "workflow:model:call:completed" &&
|
|
29
|
+
event.type !== "bug:model:call:completed") {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const record = event;
|
|
33
|
+
promptTokens += numberOf(record.promptTokens);
|
|
34
|
+
completionTokens += numberOf(record.completionTokens);
|
|
35
|
+
totalLatencyMs += numberOf(record.latencyMs);
|
|
36
|
+
requestCount += 1;
|
|
37
|
+
}
|
|
38
|
+
return { promptTokens, completionTokens, requestCount, totalLatencyMs };
|
|
39
|
+
}
|
|
40
|
+
function numberOf(value) {
|
|
41
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
42
|
+
}
|
|
43
|
+
export function buildWorkflowManifest(identity, events, report, costClassResolver, options = {}) {
|
|
44
|
+
if (options.includeDiff === true && options.redactString === undefined) {
|
|
45
|
+
throw new Error("Workflow evidence includeDiff requires a redactor.");
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
evidenceSchemaVersion: EVIDENCE_SCHEMA_VERSION,
|
|
49
|
+
run: {
|
|
50
|
+
runId: identity.runId,
|
|
51
|
+
fingerprint: identity.fingerprint,
|
|
52
|
+
harnessVersion: HARNESS_VERSION,
|
|
53
|
+
taskType: KIND_TO_TASK_TYPE[identity.kind],
|
|
54
|
+
outcome: identity.status,
|
|
55
|
+
startedAt: identity.startedAt,
|
|
56
|
+
finishedAt: identity.finishedAt,
|
|
57
|
+
durationMs: Math.max(0, identity.finishedAt - identity.startedAt),
|
|
58
|
+
},
|
|
59
|
+
model: {
|
|
60
|
+
modelId: identity.modelId,
|
|
61
|
+
costClass: costClassResolver?.(identity.modelId) ?? "unknown",
|
|
62
|
+
},
|
|
63
|
+
usageTotals: foldWorkflowUsage(events),
|
|
64
|
+
...(contextOf(identity.workspaceRoot) === undefined
|
|
65
|
+
? {}
|
|
66
|
+
: { context: contextOf(identity.workspaceRoot) }),
|
|
67
|
+
stateTransitions: [],
|
|
68
|
+
toolCalls: [],
|
|
69
|
+
commandExecutions: [],
|
|
70
|
+
verification: verificationOf(report),
|
|
71
|
+
patch: patchOf(report, options),
|
|
72
|
+
failure: undefined,
|
|
73
|
+
...(options.governedHandoff === undefined ? {} : { governedHandoff: options.governedHandoff }),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function contextOf(workspaceRoot) {
|
|
77
|
+
if (workspaceRoot === undefined) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
workspaceRoot,
|
|
82
|
+
totalCandidates: 0,
|
|
83
|
+
usedBytes: 0,
|
|
84
|
+
budgetBytes: 0,
|
|
85
|
+
droppedForBudget: 0,
|
|
86
|
+
entries: [],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// Builds, redacts, writes the workflow manifest through the store, and returns the structured
|
|
90
|
+
// EvidenceReport. Errors intentionally surface to the caller so UI/evaluation paths cannot silently
|
|
91
|
+
// claim a terminal run without a durable evidence artifact.
|
|
92
|
+
export function persistWorkflowEvidence(identity, report, events, ctx, options = {}) {
|
|
93
|
+
const redactor = createAuditRedactor({ additionalSecrets: ctx.additionalSecrets ?? [] }, ctx.env);
|
|
94
|
+
const manifest = buildWorkflowManifest(identity, events, report, ctx.costClassResolver, {
|
|
95
|
+
...options,
|
|
96
|
+
redactString: redactor,
|
|
97
|
+
});
|
|
98
|
+
const redacted = deepRedactStrings(manifest, redactor);
|
|
99
|
+
const location = ctx.store.put(redacted.run.runId, JSON.stringify(redacted));
|
|
100
|
+
return buildEvidenceReport(redacted, location);
|
|
101
|
+
}
|
|
102
|
+
function isRecord(value) {
|
|
103
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
104
|
+
}
|
|
105
|
+
// Extracts the verification audit summary from a workflow report when present. The summary is already
|
|
106
|
+
// the audit shape; the deep redact in persist re-scrubs every string leaf for defense in depth.
|
|
107
|
+
function verificationOf(report) {
|
|
108
|
+
if (!isRecord(report)) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
const summary = report.verificationSummary ?? verifiedVerificationOf(report);
|
|
112
|
+
return isRecord(summary) ? summary : undefined;
|
|
113
|
+
}
|
|
114
|
+
function verifiedVerificationOf(report) {
|
|
115
|
+
const verified = report.verified;
|
|
116
|
+
return isRecord(verified) ? verified.verification : undefined;
|
|
117
|
+
}
|
|
118
|
+
// Builds patch metadata from a workflow report. unit-tests reports carry `addedTestFiles`;
|
|
119
|
+
// bug-investigation reports carry `changedFiles`. The diff is opt-in and must be redacted before it
|
|
120
|
+
// is attached to the manifest.
|
|
121
|
+
function patchOf(report, options) {
|
|
122
|
+
if (!isRecord(report)) {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
const proposedDiff = report.proposedDiff;
|
|
126
|
+
const proposed = typeof proposedDiff === "string" && proposedDiff.length > 0;
|
|
127
|
+
const changedFiles = changedFileCount(report);
|
|
128
|
+
if (!proposed && changedFiles === 0) {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
proposed,
|
|
133
|
+
applied: patchApplied(report),
|
|
134
|
+
targetFileCount: changedFiles,
|
|
135
|
+
patchBytes: typeof proposedDiff === "string" ? Buffer.byteLength(proposedDiff, "utf8") : 0,
|
|
136
|
+
changedFiles,
|
|
137
|
+
created: 0,
|
|
138
|
+
deleted: 0,
|
|
139
|
+
...(options.includeDiff === true && typeof proposedDiff === "string" && proposedDiff.length > 0
|
|
140
|
+
? { redactedDiff: options.redactString?.(proposedDiff) }
|
|
141
|
+
: {}),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function patchApplied(report) {
|
|
145
|
+
if (report.status === "completed" || report.status === "fix-applied") {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
const verified = report.verified;
|
|
149
|
+
return isRecord(verified) && verified.patchApplied === true;
|
|
150
|
+
}
|
|
151
|
+
function changedFileCount(report) {
|
|
152
|
+
const added = report.addedTestFiles;
|
|
153
|
+
if (Array.isArray(added)) {
|
|
154
|
+
return added.length;
|
|
155
|
+
}
|
|
156
|
+
const changed = report.changedFiles;
|
|
157
|
+
return Array.isArray(changed) ? changed.length : 0;
|
|
158
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@oscharko-dev/keiko-evidence",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"description": "Internal evidence package: Keiko evidence manifests, redacted-by-construction builder, retention/rotation, EvidenceStore port + node adapter, side-file writer, and workflow-evidence mapping (ADR-0010 + ADR-0017 + ADR-0019). Not published independently.",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc -b tsconfig.json",
|
|
17
|
+
"typecheck": "tsc -b tsconfig.json",
|
|
18
|
+
"test": "vitest run"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=22"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@oscharko-dev/keiko-contracts": "0.2.0",
|
|
29
|
+
"@oscharko-dev/keiko-security": "0.2.0",
|
|
30
|
+
"@oscharko-dev/keiko-workspace": "0.2.0"
|
|
31
|
+
}
|
|
32
|
+
}
|