@oscharko-dev/keiko-contracts 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/bff-wire.d.ts +661 -0
- package/dist/bff-wire.d.ts.map +1 -0
- package/dist/bff-wire.js +102 -0
- package/dist/bug-investigation-events.d.ts +92 -0
- package/dist/bug-investigation-events.d.ts.map +1 -0
- package/dist/bug-investigation-events.js +18 -0
- package/dist/coding-context.d.ts +76 -0
- package/dist/coding-context.d.ts.map +1 -0
- package/dist/coding-context.js +158 -0
- package/dist/connected-context.d.ts +174 -0
- package/dist/connected-context.d.ts.map +1 -0
- package/dist/connected-context.js +636 -0
- package/dist/conversation-budget.d.ts +37 -0
- package/dist/conversation-budget.d.ts.map +1 -0
- package/dist/conversation-budget.js +97 -0
- package/dist/editor-agent.d.ts +131 -0
- package/dist/editor-agent.d.ts.map +1 -0
- package/dist/editor-agent.js +197 -0
- package/dist/editor-completion.d.ts +62 -0
- package/dist/editor-completion.d.ts.map +1 -0
- package/dist/editor-completion.js +147 -0
- package/dist/editor-dirty-close.d.ts +17 -0
- package/dist/editor-dirty-close.d.ts.map +1 -0
- package/dist/editor-dirty-close.js +8 -0
- package/dist/editor-hot-exit.d.ts +18 -0
- package/dist/editor-hot-exit.d.ts.map +1 -0
- package/dist/editor-hot-exit.js +42 -0
- package/dist/editor-inline-completion.d.ts +70 -0
- package/dist/editor-inline-completion.d.ts.map +1 -0
- package/dist/editor-inline-completion.js +215 -0
- package/dist/editor-layout.d.ts +105 -0
- package/dist/editor-layout.d.ts.map +1 -0
- package/dist/editor-layout.js +479 -0
- package/dist/editor-patch-apply.d.ts +77 -0
- package/dist/editor-patch-apply.d.ts.map +1 -0
- package/dist/editor-patch-apply.js +122 -0
- package/dist/editor-session.d.ts +31 -0
- package/dist/editor-session.d.ts.map +1 -0
- package/dist/editor-session.js +75 -0
- package/dist/editor-test-generation.d.ts +104 -0
- package/dist/editor-test-generation.d.ts.map +1 -0
- package/dist/editor-test-generation.js +211 -0
- package/dist/evaluations.d.ts +75 -0
- package/dist/evaluations.d.ts.map +1 -0
- package/dist/evaluations.js +16 -0
- package/dist/evidence.d.ts +297 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +9 -0
- package/dist/gateway.d.ts +129 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +66 -0
- package/dist/harness.d.ts +274 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.js +38 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/language-service.d.ts +145 -0
- package/dist/language-service.d.ts.map +1 -0
- package/dist/language-service.js +161 -0
- package/dist/local-knowledge-large-document-validation.d.ts +7 -0
- package/dist/local-knowledge-large-document-validation.d.ts.map +1 -0
- package/dist/local-knowledge-large-document-validation.js +161 -0
- package/dist/local-knowledge-large-document.d.ts +113 -0
- package/dist/local-knowledge-large-document.d.ts.map +1 -0
- package/dist/local-knowledge-large-document.js +142 -0
- package/dist/local-knowledge-paths.d.ts +3 -0
- package/dist/local-knowledge-paths.d.ts.map +1 -0
- package/dist/local-knowledge-paths.js +65 -0
- package/dist/local-knowledge-records.d.ts +190 -0
- package/dist/local-knowledge-records.d.ts.map +1 -0
- package/dist/local-knowledge-records.js +36 -0
- package/dist/local-knowledge-schema-validation.d.ts +19 -0
- package/dist/local-knowledge-schema-validation.d.ts.map +1 -0
- package/dist/local-knowledge-schema-validation.js +115 -0
- package/dist/local-knowledge-schema.d.ts +14 -0
- package/dist/local-knowledge-schema.d.ts.map +1 -0
- package/dist/local-knowledge-schema.js +715 -0
- package/dist/local-knowledge-validation.d.ts +20 -0
- package/dist/local-knowledge-validation.d.ts.map +1 -0
- package/dist/local-knowledge-validation.js +487 -0
- package/dist/local-knowledge.d.ts +158 -0
- package/dist/local-knowledge.d.ts.map +1 -0
- package/dist/local-knowledge.js +63 -0
- package/dist/memory-audit-events.d.ts +73 -0
- package/dist/memory-audit-events.d.ts.map +1 -0
- package/dist/memory-audit-events.js +44 -0
- package/dist/memory-audit-validation.d.ts +4 -0
- package/dist/memory-audit-validation.d.ts.map +1 -0
- package/dist/memory-audit-validation.js +151 -0
- package/dist/memory-barrel.d.ts +15 -0
- package/dist/memory-barrel.d.ts.map +1 -0
- package/dist/memory-barrel.js +20 -0
- package/dist/memory-internal.d.ts +26 -0
- package/dist/memory-internal.d.ts.map +1 -0
- package/dist/memory-internal.js +104 -0
- package/dist/memory-operations-validation.d.ts +12 -0
- package/dist/memory-operations-validation.d.ts.map +1 -0
- package/dist/memory-operations-validation.js +267 -0
- package/dist/memory-operations.d.ts +156 -0
- package/dist/memory-operations.d.ts.map +1 -0
- package/dist/memory-operations.js +29 -0
- package/dist/memory-record-validation.d.ts +10 -0
- package/dist/memory-record-validation.d.ts.map +1 -0
- package/dist/memory-record-validation.js +101 -0
- package/dist/memory-records.d.ts +66 -0
- package/dist/memory-records.d.ts.map +1 -0
- package/dist/memory-records.js +22 -0
- package/dist/memory-retrieval-validation.d.ts +6 -0
- package/dist/memory-retrieval-validation.d.ts.map +1 -0
- package/dist/memory-retrieval-validation.js +108 -0
- package/dist/memory-validation.d.ts +31 -0
- package/dist/memory-validation.d.ts.map +1 -0
- package/dist/memory-validation.js +318 -0
- package/dist/memory-workflow-port.d.ts +26 -0
- package/dist/memory-workflow-port.d.ts.map +1 -0
- package/dist/memory-workflow-port.js +13 -0
- package/dist/memory.d.ts +81 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +104 -0
- package/dist/prompt-enhancer-analyzer.d.ts +7 -0
- package/dist/prompt-enhancer-analyzer.d.ts.map +1 -0
- package/dist/prompt-enhancer-analyzer.js +745 -0
- package/dist/prompt-enhancer-bff.d.ts +67 -0
- package/dist/prompt-enhancer-bff.d.ts.map +1 -0
- package/dist/prompt-enhancer-bff.js +156 -0
- package/dist/prompt-enhancer-critic.d.ts +46 -0
- package/dist/prompt-enhancer-critic.d.ts.map +1 -0
- package/dist/prompt-enhancer-critic.js +35 -0
- package/dist/prompt-enhancer-grounding.d.ts +19 -0
- package/dist/prompt-enhancer-grounding.d.ts.map +1 -0
- package/dist/prompt-enhancer-grounding.js +235 -0
- package/dist/prompt-enhancer-safety.d.ts +66 -0
- package/dist/prompt-enhancer-safety.d.ts.map +1 -0
- package/dist/prompt-enhancer-safety.js +446 -0
- package/dist/prompt-enhancer-validation.d.ts +28 -0
- package/dist/prompt-enhancer-validation.d.ts.map +1 -0
- package/dist/prompt-enhancer-validation.js +931 -0
- package/dist/prompt-enhancer.d.ts +184 -0
- package/dist/prompt-enhancer.d.ts.map +1 -0
- package/dist/prompt-enhancer.js +350 -0
- package/dist/qualityIntelligence/assertNever.d.ts +2 -0
- package/dist/qualityIntelligence/assertNever.d.ts.map +1 -0
- package/dist/qualityIntelligence/assertNever.js +7 -0
- package/dist/qualityIntelligence/auditSummary.d.ts +25 -0
- package/dist/qualityIntelligence/auditSummary.d.ts.map +1 -0
- package/dist/qualityIntelligence/auditSummary.js +7 -0
- package/dist/qualityIntelligence/bffWire.d.ts +356 -0
- package/dist/qualityIntelligence/bffWire.d.ts.map +1 -0
- package/dist/qualityIntelligence/bffWire.js +22 -0
- package/dist/qualityIntelligence/coverageMap.d.ts +21 -0
- package/dist/qualityIntelligence/coverageMap.d.ts.map +1 -0
- package/dist/qualityIntelligence/coverageMap.js +29 -0
- package/dist/qualityIntelligence/editableRevision.d.ts +21 -0
- package/dist/qualityIntelligence/editableRevision.d.ts.map +1 -0
- package/dist/qualityIntelligence/editableRevision.js +8 -0
- package/dist/qualityIntelligence/evidenceAtom.d.ts +35 -0
- package/dist/qualityIntelligence/evidenceAtom.d.ts.map +1 -0
- package/dist/qualityIntelligence/evidenceAtom.js +29 -0
- package/dist/qualityIntelligence/exportBundle.d.ts +28 -0
- package/dist/qualityIntelligence/exportBundle.d.ts.map +1 -0
- package/dist/qualityIntelligence/exportBundle.js +46 -0
- package/dist/qualityIntelligence/handoffEnvelope.d.ts +23 -0
- package/dist/qualityIntelligence/handoffEnvelope.d.ts.map +1 -0
- package/dist/qualityIntelligence/handoffEnvelope.js +8 -0
- package/dist/qualityIntelligence/ids.d.ts +58 -0
- package/dist/qualityIntelligence/ids.d.ts.map +1 -0
- package/dist/qualityIntelligence/ids.js +93 -0
- package/dist/qualityIntelligence/index.d.ts +29 -0
- package/dist/qualityIntelligence/index.d.ts.map +1 -0
- package/dist/qualityIntelligence/index.js +20 -0
- package/dist/qualityIntelligence/reviewRecord.d.ts +19 -0
- package/dist/qualityIntelligence/reviewRecord.d.ts.map +1 -0
- package/dist/qualityIntelligence/reviewRecord.js +20 -0
- package/dist/qualityIntelligence/runPlanAndEvents.d.ts +84 -0
- package/dist/qualityIntelligence/runPlanAndEvents.d.ts.map +1 -0
- package/dist/qualityIntelligence/runPlanAndEvents.js +51 -0
- package/dist/qualityIntelligence/sourceEnvelope.d.ts +77 -0
- package/dist/qualityIntelligence/sourceEnvelope.d.ts.map +1 -0
- package/dist/qualityIntelligence/sourceEnvelope.js +118 -0
- package/dist/qualityIntelligence/testCaseCandidate.d.ts +21 -0
- package/dist/qualityIntelligence/testCaseCandidate.d.ts.map +1 -0
- package/dist/qualityIntelligence/testCaseCandidate.js +21 -0
- package/dist/qualityIntelligence/testQualityRubric.d.ts +17 -0
- package/dist/qualityIntelligence/testQualityRubric.d.ts.map +1 -0
- package/dist/qualityIntelligence/testQualityRubric.js +32 -0
- package/dist/qualityIntelligence/validationFinding.d.ts +48 -0
- package/dist/qualityIntelligence/validationFinding.d.ts.map +1 -0
- package/dist/qualityIntelligence/validationFinding.js +36 -0
- package/dist/relationships-validation.d.ts +13 -0
- package/dist/relationships-validation.d.ts.map +1 -0
- package/dist/relationships-validation.js +422 -0
- package/dist/relationships.d.ts +79 -0
- package/dist/relationships.d.ts.map +1 -0
- package/dist/relationships.js +307 -0
- package/dist/text-safety.d.ts +7 -0
- package/dist/text-safety.d.ts.map +1 -0
- package/dist/text-safety.js +58 -0
- package/dist/tools.d.ts +153 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +118 -0
- package/dist/unit-test-events.d.ts +87 -0
- package/dist/unit-test-events.d.ts.map +1 -0
- package/dist/unit-test-events.js +14 -0
- package/dist/verification-summary.d.ts +38 -0
- package/dist/verification-summary.d.ts.map +1 -0
- package/dist/verification-summary.js +5 -0
- package/dist/verification.d.ts +64 -0
- package/dist/verification.d.ts.map +1 -0
- package/dist/verification.js +13 -0
- package/dist/workflow-descriptor.d.ts +21 -0
- package/dist/workflow-descriptor.d.ts.map +1 -0
- package/dist/workflow-descriptor.js +8 -0
- package/dist/workflow-handoff.d.ts +69 -0
- package/dist/workflow-handoff.d.ts.map +1 -0
- package/dist/workflow-handoff.js +381 -0
- package/dist/workspace-descriptors.d.ts +21 -0
- package/dist/workspace-descriptors.d.ts.map +1 -0
- package/dist/workspace-descriptors.js +180 -0
- package/dist/workspace-ui.d.ts +119 -0
- package/dist/workspace-ui.d.ts.map +1 -0
- package/dist/workspace-ui.js +105 -0
- package/dist/workspace.d.ts +104 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +27 -0
- package/package.json +71 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare const EDITOR_SESSION_SCHEMA_VERSION: "1";
|
|
2
|
+
export interface EditorDocumentVersion {
|
|
3
|
+
readonly sizeBytes: number;
|
|
4
|
+
readonly modifiedAt: number;
|
|
5
|
+
readonly contentHash: string;
|
|
6
|
+
}
|
|
7
|
+
export interface EditorSessionAiProvenance {
|
|
8
|
+
readonly modelId: string;
|
|
9
|
+
readonly gatewayPolicyVersion: string;
|
|
10
|
+
readonly promptHash: string;
|
|
11
|
+
readonly requestId: string;
|
|
12
|
+
}
|
|
13
|
+
export interface EditorDocumentSession {
|
|
14
|
+
readonly schemaVersion: typeof EDITOR_SESSION_SCHEMA_VERSION;
|
|
15
|
+
readonly version: EditorDocumentVersion;
|
|
16
|
+
readonly aiProvenance?: EditorSessionAiProvenance;
|
|
17
|
+
}
|
|
18
|
+
export type EditorSessionErrorCode = "UNSUPPORTED_FILE" | "FILE_TOO_LARGE" | "WRITE_CONFLICT" | "DENIED" | "STALE_SESSION";
|
|
19
|
+
export declare const EDITOR_SESSION_ERROR_CODES: readonly EditorSessionErrorCode[];
|
|
20
|
+
export interface EditorSessionValidationOk<T> {
|
|
21
|
+
readonly ok: true;
|
|
22
|
+
readonly value: T;
|
|
23
|
+
}
|
|
24
|
+
export interface EditorSessionValidationFail {
|
|
25
|
+
readonly ok: false;
|
|
26
|
+
readonly errors: readonly string[];
|
|
27
|
+
}
|
|
28
|
+
export type EditorSessionValidation<T> = EditorSessionValidationOk<T> | EditorSessionValidationFail;
|
|
29
|
+
export declare function isEditorDocumentVersion(value: unknown): value is EditorDocumentVersion;
|
|
30
|
+
export declare function parseEditorDocumentVersion(value: unknown): EditorSessionValidation<EditorDocumentVersion>;
|
|
31
|
+
//# sourceMappingURL=editor-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor-session.d.ts","sourceRoot":"","sources":["../src/editor-session.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,6BAA6B,EAAG,GAAY,CAAC;AAK1D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAMD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAID,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,OAAO,6BAA6B,CAAC;IAC7D,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,yBAAyB,CAAC;CACnD;AAMD,MAAM,MAAM,sBAAsB,GAC9B,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,QAAQ,GACR,eAAe,CAAC;AAEpB,eAAO,MAAM,0BAA0B,EAAE,SAAS,sBAAsB,EAM9D,CAAC;AAMX,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CACnB;AACD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AACD,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,yBAAyB,CAAC,CAAC,CAAC,GAAG,2BAA2B,CAAC;AA0BpG,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAOtF;AAID,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,uBAAuB,CAAC,qBAAqB,CAAC,CAyBhD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Governed editor-session contracts (Issue #1197, Epic #1189). These shapes generalize the
|
|
2
|
+
// existing file read/write surface into editor-session metadata so the editor, deterministic
|
|
3
|
+
// diagnostics (#1198), and model-backed completion (#1199) can correlate "the content the user
|
|
4
|
+
// is editing" with "the content the server reasoned over" — without ever echoing file content.
|
|
5
|
+
//
|
|
6
|
+
// This module owns the editor-session / file-state contract namespace for the epic. It is kept
|
|
7
|
+
// disjoint from the language-service namespace (#1198): no name overlaps, no shared types.
|
|
8
|
+
//
|
|
9
|
+
// Leaf-package rules (ADR-0019): pure types and frozen const tables only. No filesystem, no
|
|
10
|
+
// clock, no crypto, no randomness, and no imports of other `@oscharko-dev/keiko-*` packages.
|
|
11
|
+
// The content-free `contentHash` is computed by producers (the BFF) with `node:crypto` and only
|
|
12
|
+
// inspected here as an opaque hex string.
|
|
13
|
+
// Schema version for the editor-session metadata envelope. Bump as a new string member when the
|
|
14
|
+
// shape changes incompatibly; consumers pin against the literal to detect skew.
|
|
15
|
+
export const EDITOR_SESSION_SCHEMA_VERSION = "1";
|
|
16
|
+
export const EDITOR_SESSION_ERROR_CODES = [
|
|
17
|
+
"UNSUPPORTED_FILE",
|
|
18
|
+
"FILE_TOO_LARGE",
|
|
19
|
+
"WRITE_CONFLICT",
|
|
20
|
+
"DENIED",
|
|
21
|
+
"STALE_SESSION",
|
|
22
|
+
];
|
|
23
|
+
const SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
24
|
+
function isRecord(value) {
|
|
25
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26
|
+
}
|
|
27
|
+
// A byte count: a non-negative integer. Fractional byte counts can never match the filesystem
|
|
28
|
+
// `stats.size`, so they are rejected up front rather than silently yielding a stale-session 409.
|
|
29
|
+
function isNonNegativeInteger(value) {
|
|
30
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
31
|
+
}
|
|
32
|
+
// `modifiedAt` mirrors `stats.mtimeMs`, which carries sub-millisecond fractional precision, so it
|
|
33
|
+
// is validated as a finite non-negative number rather than an integer.
|
|
34
|
+
function isFiniteNonNegativeNumber(value) {
|
|
35
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
36
|
+
}
|
|
37
|
+
function isSha256Hex(value) {
|
|
38
|
+
return typeof value === "string" && SHA256_HEX.test(value);
|
|
39
|
+
}
|
|
40
|
+
// Strict structural guard. Unknown extra keys are tolerated (forward-compatible wire); the three
|
|
41
|
+
// required fields must be present with valid values.
|
|
42
|
+
export function isEditorDocumentVersion(value) {
|
|
43
|
+
return (isRecord(value) &&
|
|
44
|
+
isNonNegativeInteger(value.sizeBytes) &&
|
|
45
|
+
isFiniteNonNegativeNumber(value.modifiedAt) &&
|
|
46
|
+
isSha256Hex(value.contentHash));
|
|
47
|
+
}
|
|
48
|
+
// Validates an `unknown` payload into an EditorDocumentVersion, reporting one error per failed
|
|
49
|
+
// invariant. The BFF uses this to reject a malformed client-supplied baseVersion with 400.
|
|
50
|
+
export function parseEditorDocumentVersion(value) {
|
|
51
|
+
if (!isRecord(value)) {
|
|
52
|
+
return { ok: false, errors: ["baseVersion must be an object"] };
|
|
53
|
+
}
|
|
54
|
+
const errors = [];
|
|
55
|
+
if (!isNonNegativeInteger(value.sizeBytes)) {
|
|
56
|
+
errors.push("baseVersion.sizeBytes must be a non-negative integer");
|
|
57
|
+
}
|
|
58
|
+
if (!isFiniteNonNegativeNumber(value.modifiedAt)) {
|
|
59
|
+
errors.push("baseVersion.modifiedAt must be a finite non-negative number");
|
|
60
|
+
}
|
|
61
|
+
if (!isSha256Hex(value.contentHash)) {
|
|
62
|
+
errors.push("baseVersion.contentHash must be a lowercase hex SHA-256 string");
|
|
63
|
+
}
|
|
64
|
+
if (errors.length > 0) {
|
|
65
|
+
return { ok: false, errors };
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
ok: true,
|
|
69
|
+
value: {
|
|
70
|
+
sizeBytes: value.sizeBytes,
|
|
71
|
+
modifiedAt: value.modifiedAt,
|
|
72
|
+
contentHash: value.contentHash,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { type LanguageDocumentOverlay, type LanguageRange } from "./language-service.js";
|
|
2
|
+
import type { EditorCompletionContextSelectors } from "./editor-completion.js";
|
|
3
|
+
import type { CodingContextWirePack } from "./coding-context.js";
|
|
4
|
+
export declare const EDITOR_TEST_GENERATION_SCHEMA_VERSION: "1";
|
|
5
|
+
export declare const EDITOR_TEST_GENERATION_STABILITY_RUNS: 5;
|
|
6
|
+
export type EditorTestGenerationTargetKind = "file" | "selection" | "symbol" | "changed-file-set" | "frontend-component";
|
|
7
|
+
export declare const EDITOR_TEST_GENERATION_TARGET_KINDS: readonly EditorTestGenerationTargetKind[];
|
|
8
|
+
export interface EditorTestGenerationWireSymbol {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly container?: string;
|
|
11
|
+
readonly range: LanguageRange;
|
|
12
|
+
}
|
|
13
|
+
export type EditorTestGenerationWireTarget = {
|
|
14
|
+
readonly kind: "file";
|
|
15
|
+
readonly document: LanguageDocumentOverlay;
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: "selection";
|
|
18
|
+
readonly document: LanguageDocumentOverlay;
|
|
19
|
+
readonly range: LanguageRange;
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: "symbol";
|
|
22
|
+
readonly document: LanguageDocumentOverlay;
|
|
23
|
+
readonly symbol: EditorTestGenerationWireSymbol;
|
|
24
|
+
} | {
|
|
25
|
+
readonly kind: "changed-file-set";
|
|
26
|
+
readonly documents: readonly LanguageDocumentOverlay[];
|
|
27
|
+
} | {
|
|
28
|
+
readonly kind: "frontend-component";
|
|
29
|
+
readonly document: LanguageDocumentOverlay;
|
|
30
|
+
readonly componentName: string;
|
|
31
|
+
readonly range?: LanguageRange;
|
|
32
|
+
};
|
|
33
|
+
export interface EditorTestGenerationWireRequest {
|
|
34
|
+
readonly schemaVersion: typeof EDITOR_TEST_GENERATION_SCHEMA_VERSION;
|
|
35
|
+
readonly root: string;
|
|
36
|
+
readonly target: EditorTestGenerationWireTarget;
|
|
37
|
+
readonly contextBudgetBytes: number;
|
|
38
|
+
readonly context?: EditorCompletionContextSelectors;
|
|
39
|
+
}
|
|
40
|
+
export type EditorTestGenerationStatus = "disabled" | "deferred" | "generated" | "failed";
|
|
41
|
+
export declare const EDITOR_TEST_GENERATION_STATUSES: readonly EditorTestGenerationStatus[];
|
|
42
|
+
export type EditorTestGenerationAssurance = "unverified" | "assured";
|
|
43
|
+
export declare const EDITOR_TEST_GENERATION_ASSURANCES: readonly EditorTestGenerationAssurance[];
|
|
44
|
+
export type EditorTestGenerationGateState = "passed" | "failed" | "not-run";
|
|
45
|
+
export declare const EDITOR_TEST_GENERATION_GATE_STATES: readonly EditorTestGenerationGateState[];
|
|
46
|
+
export interface EditorTestGenerationFunnel {
|
|
47
|
+
readonly executionEnabled: boolean;
|
|
48
|
+
readonly candidatesGenerated: number;
|
|
49
|
+
readonly candidatesSurfaced: number;
|
|
50
|
+
readonly stabilityRunsRequired: number;
|
|
51
|
+
readonly build: EditorTestGenerationGateState;
|
|
52
|
+
readonly pass: EditorTestGenerationGateState;
|
|
53
|
+
readonly stability: EditorTestGenerationGateState;
|
|
54
|
+
readonly coverage: EditorTestGenerationGateState;
|
|
55
|
+
readonly mutation: EditorTestGenerationGateState;
|
|
56
|
+
readonly antiTautology: EditorTestGenerationGateState;
|
|
57
|
+
readonly coverageLineDelta?: number | undefined;
|
|
58
|
+
readonly coverageBranchDelta?: number | undefined;
|
|
59
|
+
readonly mutantsKilled?: number | undefined;
|
|
60
|
+
readonly mutantsTotal?: number | undefined;
|
|
61
|
+
}
|
|
62
|
+
export type EditorTestGenerationWireChangeKind = "added" | "modified" | "deleted";
|
|
63
|
+
export interface EditorTestGenerationWireEdit {
|
|
64
|
+
readonly range: LanguageRange;
|
|
65
|
+
readonly newText: string;
|
|
66
|
+
}
|
|
67
|
+
export interface EditorTestGenerationWireFileChange {
|
|
68
|
+
readonly path: string;
|
|
69
|
+
readonly changeKind: EditorTestGenerationWireChangeKind;
|
|
70
|
+
readonly edits: readonly EditorTestGenerationWireEdit[];
|
|
71
|
+
}
|
|
72
|
+
export interface EditorTestGenerationWirePatch {
|
|
73
|
+
readonly patchId: string;
|
|
74
|
+
readonly files: readonly EditorTestGenerationWireFileChange[];
|
|
75
|
+
}
|
|
76
|
+
export interface EditorTestGenerationWireProvenance {
|
|
77
|
+
readonly modelId: string;
|
|
78
|
+
readonly gatewayPolicyVersion: string;
|
|
79
|
+
readonly promptHash: string;
|
|
80
|
+
readonly producedAt: number;
|
|
81
|
+
}
|
|
82
|
+
export interface EditorTestGenerationWireResponse {
|
|
83
|
+
readonly schemaVersion: typeof EDITOR_TEST_GENERATION_SCHEMA_VERSION;
|
|
84
|
+
readonly status: EditorTestGenerationStatus;
|
|
85
|
+
readonly reason?: string;
|
|
86
|
+
readonly assurance?: EditorTestGenerationAssurance;
|
|
87
|
+
readonly funnel: EditorTestGenerationFunnel;
|
|
88
|
+
readonly context?: CodingContextWirePack;
|
|
89
|
+
readonly patch?: EditorTestGenerationWirePatch;
|
|
90
|
+
readonly provenance?: EditorTestGenerationWireProvenance;
|
|
91
|
+
readonly applyableDiff?: string;
|
|
92
|
+
}
|
|
93
|
+
export declare function notRunTestGenerationFunnel(): EditorTestGenerationFunnel;
|
|
94
|
+
export interface EditorTestGenerationParseOk {
|
|
95
|
+
readonly ok: true;
|
|
96
|
+
readonly value: EditorTestGenerationWireRequest;
|
|
97
|
+
}
|
|
98
|
+
export interface EditorTestGenerationParseFail {
|
|
99
|
+
readonly ok: false;
|
|
100
|
+
readonly errors: readonly string[];
|
|
101
|
+
}
|
|
102
|
+
export type EditorTestGenerationParse = EditorTestGenerationParseOk | EditorTestGenerationParseFail;
|
|
103
|
+
export declare function parseEditorTestGenerationRequest(value: unknown): EditorTestGenerationParse;
|
|
104
|
+
//# sourceMappingURL=editor-test-generation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor-test-generation.d.ts","sourceRoot":"","sources":["../src/editor-test-generation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// Editor-driven test-generation WIRE contract (Issue #1202, Epic #1189, ADR-0042 D7).
|
|
2
|
+
// These are the request/response shapes the `POST /api/editor/test-generation` BFF route consumes and
|
|
3
|
+
// emits. The route is the governed seam between the browser-tier `@oscharko-dev/keiko-editor`
|
|
4
|
+
// "Generate Tests" action (which renders a reviewable diff only) and the server-owned, gated
|
|
5
|
+
// unit-test-generation workflow (`@oscharko-dev/keiko-workflows`) enriched with governed coding
|
|
6
|
+
// context (#1211, `purpose: "test-generation"`).
|
|
7
|
+
//
|
|
8
|
+
// Wave-2 surface, shipped switched off (ADR-0042 D7). Editor-driven test generation, execution, and
|
|
9
|
+
// verification execute untrusted, model-generated code through an assured pre-filter and are therefore
|
|
10
|
+
// deferred behind a default-off feature flag that may be enabled only once a deny-by-default network
|
|
11
|
+
// egress boundary is enforced and proven by an automated test (`tools.ts` `network: "inherit"`;
|
|
12
|
+
// `limits.ts` `enforced: false`; "Keiko is not a sandbox"). The route therefore exposes two gates:
|
|
13
|
+
// - `disabled` — the feature flag is off (the v1 default). No retrieval, no model, no execution.
|
|
14
|
+
// - `deferred` — the feature is enabled but the assured-execution (egress) boundary is not enforced,
|
|
15
|
+
// so no model-generated code is produced or executed; governed discovery still runs for provenance.
|
|
16
|
+
// - `generated` — a reviewable candidate patch was produced (reachable only once the egress boundary
|
|
17
|
+
// is enforced); in v1 every funnel gate is `not-run` and a candidate can only ever be `unverified`.
|
|
18
|
+
// - `failed` — a content-free, actionable failure; the editor stays usable.
|
|
19
|
+
//
|
|
20
|
+
// Content boundary: the REQUEST carries the in-editor buffer text (the document overlay) — the user's
|
|
21
|
+
// own buffer travelling over the loopback BFF, exactly like the language-service (#1198) and completion
|
|
22
|
+
// (#1199) requests; it is never logged. The RESPONSE is content-free apart from the reviewable patch
|
|
23
|
+
// edits (`newText`), which are the candidate test code the user explicitly reviews and applies into
|
|
24
|
+
// their own workspace: no raw prompt, no raw model reasoning, no retrieved excerpt, no secret. Status,
|
|
25
|
+
// reason, funnel, assurance, provenance, and the coding-context citations are counts, hashes, enum
|
|
26
|
+
// literals, and content-free pointers only (EU AI Act Reg. (EU) 2024/1689 Art. 12 record-keeping).
|
|
27
|
+
//
|
|
28
|
+
// Leaf-package rules (ADR-0019): pure types and frozen const tables plus throw-free validators only.
|
|
29
|
+
// No filesystem, no clock, no crypto, no randomness, and no imports of other `@oscharko-dev/keiko-*`
|
|
30
|
+
// packages. Geometry, the document-overlay shape, and the coding-context selectors/citations are reused
|
|
31
|
+
// from the sibling editor contracts so the test-generation tier shares one stable provenance model with
|
|
32
|
+
// the completion and inline-completion gateways.
|
|
33
|
+
import { isLanguageDocumentOverlay, isLanguagePosition, } from "./language-service.js";
|
|
34
|
+
// Schema version for the test-generation envelope. Bump as a new string member when the shape changes
|
|
35
|
+
// incompatibly; consumers pin against the literal to detect skew.
|
|
36
|
+
export const EDITOR_TEST_GENERATION_SCHEMA_VERSION = "1";
|
|
37
|
+
// The minimum number of stable executions a generated test must survive in the assured pre-filter
|
|
38
|
+
// before it may be surfaced as apply-ready (Review Addendum — Meta "Automated Unit Test Improvement",
|
|
39
|
+
// FSE 2024). Reported in the funnel so a consumer can audit the wave-2 enablement target even while the
|
|
40
|
+
// pre-filter is `not-run`.
|
|
41
|
+
export const EDITOR_TEST_GENERATION_STABILITY_RUNS = 5;
|
|
42
|
+
export const EDITOR_TEST_GENERATION_TARGET_KINDS = [
|
|
43
|
+
"file",
|
|
44
|
+
"selection",
|
|
45
|
+
"symbol",
|
|
46
|
+
"changed-file-set",
|
|
47
|
+
"frontend-component",
|
|
48
|
+
];
|
|
49
|
+
export const EDITOR_TEST_GENERATION_STATUSES = [
|
|
50
|
+
"disabled",
|
|
51
|
+
"deferred",
|
|
52
|
+
"generated",
|
|
53
|
+
"failed",
|
|
54
|
+
];
|
|
55
|
+
export const EDITOR_TEST_GENERATION_ASSURANCES = [
|
|
56
|
+
"unverified",
|
|
57
|
+
"assured",
|
|
58
|
+
];
|
|
59
|
+
export const EDITOR_TEST_GENERATION_GATE_STATES = [
|
|
60
|
+
"passed",
|
|
61
|
+
"failed",
|
|
62
|
+
"not-run",
|
|
63
|
+
];
|
|
64
|
+
// Builds the v1 funnel: no execution, every gate `not-run`, no candidates. The single authority for the
|
|
65
|
+
// "switched-off" funnel so the route and its tests cannot drift.
|
|
66
|
+
export function notRunTestGenerationFunnel() {
|
|
67
|
+
return {
|
|
68
|
+
executionEnabled: false,
|
|
69
|
+
candidatesGenerated: 0,
|
|
70
|
+
candidatesSurfaced: 0,
|
|
71
|
+
stabilityRunsRequired: EDITOR_TEST_GENERATION_STABILITY_RUNS,
|
|
72
|
+
build: "not-run",
|
|
73
|
+
pass: "not-run",
|
|
74
|
+
stability: "not-run",
|
|
75
|
+
coverage: "not-run",
|
|
76
|
+
mutation: "not-run",
|
|
77
|
+
antiTautology: "not-run",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function isRecord(value) {
|
|
81
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
82
|
+
}
|
|
83
|
+
function isNonEmptyString(value) {
|
|
84
|
+
return typeof value === "string" && value.length > 0;
|
|
85
|
+
}
|
|
86
|
+
function isNonNegativeInteger(value) {
|
|
87
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
88
|
+
}
|
|
89
|
+
function isStringArray(value) {
|
|
90
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
91
|
+
}
|
|
92
|
+
// A LanguageRange is `{ start, end }` of two LanguagePositions. Defined locally because the
|
|
93
|
+
// language-service module exposes only the position guard; this keeps the test-generation contract a
|
|
94
|
+
// leaf with no new shared dependency.
|
|
95
|
+
function isWireRange(value) {
|
|
96
|
+
return isRecord(value) && isLanguagePosition(value.start) && isLanguagePosition(value.end);
|
|
97
|
+
}
|
|
98
|
+
function isWireSymbol(value) {
|
|
99
|
+
return (isRecord(value) &&
|
|
100
|
+
isNonEmptyString(value.name) &&
|
|
101
|
+
(value.container === undefined || typeof value.container === "string") &&
|
|
102
|
+
isWireRange(value.range));
|
|
103
|
+
}
|
|
104
|
+
function isOverlayArray(value) {
|
|
105
|
+
return Array.isArray(value) && value.length > 0 && value.every(isLanguageDocumentOverlay);
|
|
106
|
+
}
|
|
107
|
+
// Collects the optional, content-bearing context selectors (identical invariants to the completion
|
|
108
|
+
// gateway). Unknown-typed fields are rejected so a malformed selector cannot silently widen retrieval;
|
|
109
|
+
// an absent `context` is valid.
|
|
110
|
+
function collectContextErrors(context, errors) {
|
|
111
|
+
if (context === undefined) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!isRecord(context)) {
|
|
115
|
+
errors.push("context must be an object when provided");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
for (const field of ["queryText", "symbol", "capsuleId", "capsuleSetId"]) {
|
|
119
|
+
if (context[field] !== undefined && typeof context[field] !== "string") {
|
|
120
|
+
errors.push(`context.${field} must be a string when provided`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (context.changedFiles !== undefined && !isStringArray(context.changedFiles)) {
|
|
124
|
+
errors.push("context.changedFiles must be an array of strings when provided");
|
|
125
|
+
}
|
|
126
|
+
if (context.capsuleId !== undefined && context.capsuleSetId !== undefined) {
|
|
127
|
+
errors.push("context must not set both capsuleId and capsuleSetId");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Collects the shape errors for a single-document target (file/selection/symbol/frontend-component).
|
|
131
|
+
function collectScopedTargetErrors(kind, target, errors) {
|
|
132
|
+
if (!isLanguageDocumentOverlay(target.document)) {
|
|
133
|
+
errors.push("target.document must be { path, languageId, text }");
|
|
134
|
+
}
|
|
135
|
+
if (kind === "selection" && !isWireRange(target.range)) {
|
|
136
|
+
errors.push("target.range must be { start, end } for a selection target");
|
|
137
|
+
}
|
|
138
|
+
if (kind === "symbol" && !isWireSymbol(target.symbol)) {
|
|
139
|
+
errors.push("target.symbol must be { name, range } for a symbol target");
|
|
140
|
+
}
|
|
141
|
+
if (kind === "frontend-component" && !isNonEmptyString(target.componentName)) {
|
|
142
|
+
errors.push("target.componentName must be a non-empty string for a frontend-component target");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Collects the target-shape errors for one wire target, dispatching on `kind`.
|
|
146
|
+
function collectTargetErrors(target, errors) {
|
|
147
|
+
if (!isRecord(target)) {
|
|
148
|
+
errors.push("target must be an object");
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const kind = target.kind;
|
|
152
|
+
if (typeof kind !== "string" ||
|
|
153
|
+
!EDITOR_TEST_GENERATION_TARGET_KINDS.includes(kind)) {
|
|
154
|
+
errors.push(`target.kind must be one of: ${EDITOR_TEST_GENERATION_TARGET_KINDS.join(", ")}`);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (kind === "changed-file-set") {
|
|
158
|
+
if (!isOverlayArray(target.documents)) {
|
|
159
|
+
errors.push("target.documents must be a non-empty array of { path, languageId, text }");
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
collectScopedTargetErrors(kind, target, errors);
|
|
164
|
+
}
|
|
165
|
+
function collectRequestErrors(value) {
|
|
166
|
+
const errors = [];
|
|
167
|
+
if (value.schemaVersion !== EDITOR_TEST_GENERATION_SCHEMA_VERSION) {
|
|
168
|
+
errors.push(`schemaVersion must be ${EDITOR_TEST_GENERATION_SCHEMA_VERSION}`);
|
|
169
|
+
}
|
|
170
|
+
if (!isNonEmptyString(value.root)) {
|
|
171
|
+
errors.push("root must be a non-empty string");
|
|
172
|
+
}
|
|
173
|
+
collectTargetErrors(value.target, errors);
|
|
174
|
+
if (!isNonNegativeInteger(value.contextBudgetBytes)) {
|
|
175
|
+
errors.push("contextBudgetBytes must be a non-negative integer");
|
|
176
|
+
}
|
|
177
|
+
collectContextErrors(value.context, errors);
|
|
178
|
+
return errors;
|
|
179
|
+
}
|
|
180
|
+
function buildContextSelectors(context) {
|
|
181
|
+
return {
|
|
182
|
+
...(typeof context.queryText === "string" ? { queryText: context.queryText } : {}),
|
|
183
|
+
...(typeof context.symbol === "string" ? { symbol: context.symbol } : {}),
|
|
184
|
+
...(isStringArray(context.changedFiles) ? { changedFiles: context.changedFiles } : {}),
|
|
185
|
+
...(typeof context.capsuleId === "string" ? { capsuleId: context.capsuleId } : {}),
|
|
186
|
+
...(typeof context.capsuleSetId === "string" ? { capsuleSetId: context.capsuleSetId } : {}),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
// Validates an `unknown` payload into an EditorTestGenerationWireRequest, reporting one error per failed
|
|
190
|
+
// invariant. The BFF uses this to reject a malformed request with 400 INVALID_REQUEST. The narrowed
|
|
191
|
+
// `target` is taken verbatim after validation so the discriminated variants stay intact.
|
|
192
|
+
export function parseEditorTestGenerationRequest(value) {
|
|
193
|
+
if (!isRecord(value)) {
|
|
194
|
+
return { ok: false, errors: ["request must be an object"] };
|
|
195
|
+
}
|
|
196
|
+
const errors = collectRequestErrors(value);
|
|
197
|
+
if (errors.length > 0) {
|
|
198
|
+
return { ok: false, errors };
|
|
199
|
+
}
|
|
200
|
+
const context = isRecord(value.context) ? buildContextSelectors(value.context) : undefined;
|
|
201
|
+
return {
|
|
202
|
+
ok: true,
|
|
203
|
+
value: {
|
|
204
|
+
schemaVersion: EDITOR_TEST_GENERATION_SCHEMA_VERSION,
|
|
205
|
+
root: value.root,
|
|
206
|
+
target: value.target,
|
|
207
|
+
contextBudgetBytes: value.contextBudgetBytes,
|
|
208
|
+
...(context !== undefined && Object.keys(context).length > 0 ? { context } : {}),
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { NormalizedResponse } from "./gateway.js";
|
|
2
|
+
export type EvaluationDimension = "task-completion" | "patch-correctness" | "test-pass-rate" | "verification-completeness" | "patch-size" | "audit-completeness" | "unsafe-action-rejection";
|
|
3
|
+
export declare const EVALUATION_DIMENSIONS: readonly EvaluationDimension[];
|
|
4
|
+
export interface FixtureOracle {
|
|
5
|
+
readonly expectedStatuses: readonly string[];
|
|
6
|
+
readonly expectPatch: boolean;
|
|
7
|
+
readonly expectVerificationSkip: boolean;
|
|
8
|
+
readonly maxExpectedChangedFiles: number;
|
|
9
|
+
readonly maxExpectedPatchBytes: number;
|
|
10
|
+
}
|
|
11
|
+
export type WorkflowKind = "unit-tests" | "bug-investigation";
|
|
12
|
+
export interface EvaluationFixture {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly workflowKind: WorkflowKind;
|
|
15
|
+
readonly workspaceFiles: Record<string, string>;
|
|
16
|
+
readonly workflowInput: Record<string, unknown>;
|
|
17
|
+
readonly apply?: boolean | undefined;
|
|
18
|
+
readonly mockTranscript: readonly (NormalizedResponse | Error)[];
|
|
19
|
+
readonly dimensions: ReadonlySet<EvaluationDimension>;
|
|
20
|
+
readonly oracle: FixtureOracle;
|
|
21
|
+
}
|
|
22
|
+
export type DimensionOutcome = "pass" | "fail" | "not-applicable";
|
|
23
|
+
export interface DimensionResult {
|
|
24
|
+
readonly dimension: EvaluationDimension;
|
|
25
|
+
readonly outcome: DimensionOutcome;
|
|
26
|
+
readonly reason?: string | undefined;
|
|
27
|
+
}
|
|
28
|
+
export interface FixtureRunResult {
|
|
29
|
+
readonly fixtureName: string;
|
|
30
|
+
readonly workflowKind: WorkflowKind;
|
|
31
|
+
readonly durationMs: number;
|
|
32
|
+
readonly dimensionResults: readonly DimensionResult[];
|
|
33
|
+
readonly report: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
export interface ScorecardEntry {
|
|
36
|
+
readonly dimension: EvaluationDimension;
|
|
37
|
+
readonly passCount: number;
|
|
38
|
+
readonly failCount: number;
|
|
39
|
+
readonly notApplicableCount: number;
|
|
40
|
+
readonly passRate: number | null;
|
|
41
|
+
}
|
|
42
|
+
export interface SurfaceParityCheckResult {
|
|
43
|
+
readonly check: string;
|
|
44
|
+
readonly workflowKind: WorkflowKind;
|
|
45
|
+
readonly passed: boolean;
|
|
46
|
+
readonly reason?: string | undefined;
|
|
47
|
+
}
|
|
48
|
+
export interface SurfaceParityResult {
|
|
49
|
+
readonly allPassed: boolean;
|
|
50
|
+
readonly checks: readonly SurfaceParityCheckResult[];
|
|
51
|
+
}
|
|
52
|
+
export interface LiveRunContext {
|
|
53
|
+
readonly modelId: string;
|
|
54
|
+
readonly configDescriptor: string;
|
|
55
|
+
readonly evidenceRefs: readonly string[];
|
|
56
|
+
}
|
|
57
|
+
export declare const EVAL_SCORECARD_SCHEMA_VERSION: "1";
|
|
58
|
+
export interface ScorecardSummary {
|
|
59
|
+
readonly totalFixtures: number;
|
|
60
|
+
readonly fullyPassedFixtures: number;
|
|
61
|
+
readonly safetyGatePassed: boolean;
|
|
62
|
+
readonly pilotReadyIndicator: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface EvalScorecard {
|
|
65
|
+
readonly schemaVersion: typeof EVAL_SCORECARD_SCHEMA_VERSION;
|
|
66
|
+
readonly evaluatedAt: string;
|
|
67
|
+
readonly mode: EvaluationMode;
|
|
68
|
+
readonly liveRunContext?: LiveRunContext | undefined;
|
|
69
|
+
readonly dimensions: readonly ScorecardEntry[];
|
|
70
|
+
readonly surfaceParity: SurfaceParityResult;
|
|
71
|
+
readonly fixtureResults: readonly FixtureRunResult[];
|
|
72
|
+
readonly summary: ScorecardSummary;
|
|
73
|
+
}
|
|
74
|
+
export type EvaluationMode = "offline" | "live";
|
|
75
|
+
//# sourceMappingURL=evaluations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluations.d.ts","sourceRoot":"","sources":["../src/evaluations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// All evaluation interfaces and type aliases for the Wave 1 evaluation harness (ADR-0012 D6/D8/D11).
|
|
2
|
+
// No runtime logic lives here beyond the frozen schema-version constant the type layer exposes as a
|
|
3
|
+
// value. `readonly` everywhere; optional props are `| undefined` because exactOptionalPropertyTypes
|
|
4
|
+
// is on. Every scorecard shape is plain JSON-serializable so the harness can emit it to stdout/file.
|
|
5
|
+
// The seven scored dimensions in their canonical scorecard order. A scorecard always carries one
|
|
6
|
+
// ScorecardEntry per name here, even when no fixture exercises the dimension (all not-applicable).
|
|
7
|
+
export const EVALUATION_DIMENSIONS = [
|
|
8
|
+
"task-completion",
|
|
9
|
+
"patch-correctness",
|
|
10
|
+
"test-pass-rate",
|
|
11
|
+
"verification-completeness",
|
|
12
|
+
"patch-size",
|
|
13
|
+
"audit-completeness",
|
|
14
|
+
"unsafe-action-rejection",
|
|
15
|
+
];
|
|
16
|
+
export const EVAL_SCORECARD_SCHEMA_VERSION = "1";
|