@dailephd/my-dev-kit-lab 0.4.3 → 0.4.4

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.
Files changed (35) hide show
  1. package/README.md +6 -1
  2. package/dist/src/evaluation/stageContextExpectations/producerReadinessExpectationTypes.js +8 -0
  3. package/dist/src/evaluation/stageContextExpectations/validation.js +200 -0
  4. package/dist/src/evaluation/stageContextMetrics/calculateAllocationMetrics.js +96 -0
  5. package/dist/src/evaluation/stageContextMetrics/calculateCriticalityMetrics.js +112 -0
  6. package/dist/src/evaluation/stageContextMetrics/calculateOwnerMetrics.js +84 -0
  7. package/dist/src/evaluation/stageContextMetrics/calculateReadinessAgreement.js +152 -0
  8. package/dist/src/evaluation/stageContextMetrics/calculateSupplementalRawAgreement.js +50 -0
  9. package/dist/src/evaluation/stageContextMetrics/calculateTruncationClassification.js +44 -0
  10. package/dist/src/evaluation/stageContextMetrics/evaluateProducerReadinessBridge.js +127 -0
  11. package/dist/src/evaluation/stageContextMetrics/index.js +7 -0
  12. package/dist/src/evaluation/stageContextMetrics/producerReadinessMetricTypes.js +1 -0
  13. package/dist/src/evaluation/stageContextSelectors/contextArtifactConsistency.js +10 -0
  14. package/dist/src/evaluation/upstreamArtifacts/index.js +6 -0
  15. package/dist/src/evaluation/upstreamArtifacts/orchestratorContextReadinessResultV1.js +247 -0
  16. package/dist/src/evaluation/upstreamArtifacts/readImplementationContextPacketV1.js +9 -0
  17. package/dist/src/evaluation/upstreamArtifacts/readImplementationContextRetrievalReportV1.js +9 -0
  18. package/dist/src/evaluation/upstreamArtifacts/readSupplementalContextTextFile.js +29 -0
  19. package/dist/src/evaluation/upstreamArtifacts/readTestContextPacketV1.js +9 -0
  20. package/dist/src/evaluation/upstreamArtifacts/readTestContextRetrievalReportV1.js +9 -0
  21. package/dist/src/evaluation/upstreamArtifacts/supplementalContextTextParser.js +75 -0
  22. package/dist/src/evaluation/upstreamArtifacts/supplementalContextTypes.js +152 -0
  23. package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitRetrievalAuditRecordV1.js +9 -2
  24. package/dist/src/evaluation/upstreamArtifacts/validateSupplementalContextDocumentV1.js +148 -0
  25. package/dist/src/experiments/plugins/contextStrategyComparison/loadV043StrategyArtifacts.js +117 -6
  26. package/dist/src/experiments/plugins/contextStrategyComparison/runV043StageContextStrategyWithAssurance.js +18 -3
  27. package/dist/src/experiments/plugins/contextStrategyComparison/validateV043StrategyInput.js +17 -3
  28. package/dist/src/report/experiments/buildContextStrategyComparisonV043Report.js +122 -0
  29. package/dist/src/report/experiments/renderContextStrategyComparisonV043Html.js +62 -0
  30. package/dist/src/report/experiments/renderPluginExperimentReportText.js +67 -0
  31. package/docs/METRICS.md +28 -0
  32. package/package.json +2 -2
  33. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/PROVENANCE.txt +13 -0
  34. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/context-capsule.json +7874 -0
  35. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/retrieval-audit-record.json +1076 -0
@@ -0,0 +1,247 @@
1
+ // Lab-owned bounded plain-object adapter for the frozen my-dev-kit-orchestrator
2
+ // ContextReadinessResult (commit bc08a05d3b52a629e7e4504372af199c324c4ae4,
3
+ // src/instructions/contextReadiness.ts). At the frozen commit, readiness is never
4
+ // serialized to a stable file artifact -- `check`/`export` only render it as formatted
5
+ // text (src/commands/check.ts, src/commands/export.ts). This adapter therefore
6
+ // validates and normalizes a plain object (as constructed by a caller that already has
7
+ // an in-memory readiness result -- e.g. a future integration or a test fixture), rather
8
+ // than parsing a file. It never imports orchestrator runtime code and never
9
+ // recomputes/reevaluates readiness, producer parity, or issue prioritization -- it only
10
+ // preserves what is already declared on the object.
11
+ import { makeFailure } from "./runtimeValidation.js";
12
+ import { VALID_ADEQUACY_VALUES, VALID_FRESHNESS_VALUES, VALID_TRUNCATION_VALUES } from "./supplementalContextTypes.js";
13
+ const ARTIFACT_KIND = "orchestrator-context-readiness-result-v1";
14
+ export const READINESS_DECISIONS = ["not-required", "ready", "refresh-required"];
15
+ export const READINESS_CLASSIFICATIONS = [
16
+ "not-required",
17
+ "ready",
18
+ "missing",
19
+ "template",
20
+ "partial",
21
+ "malformed",
22
+ "unsupported-schema",
23
+ "incompatible",
24
+ "source-reference-missing",
25
+ "source-reference-unreadable",
26
+ "source-evidence-malformed",
27
+ "source-evidence-unsupported-schema",
28
+ "role-mismatch",
29
+ "repository-scope-mismatch",
30
+ "repository-identity-incomplete",
31
+ "index-identity-incomplete",
32
+ "index-identity-mismatch",
33
+ "freshness-unknown",
34
+ "stale",
35
+ "adequacy-unknown",
36
+ "inadequate",
37
+ "conflict",
38
+ "required-evidence-truncated",
39
+ "required-evidence-incomplete",
40
+ "provenance-missing",
41
+ "test-strategy-missing",
42
+ "test-responsibility-invalid",
43
+ "test-responsibility-criticality-unknown",
44
+ "responsibility-mappings-truncated",
45
+ "critical-responsibilities-unmapped"
46
+ ];
47
+ function isPlainObject(value) {
48
+ return typeof value === "object" && value !== null && !Array.isArray(value);
49
+ }
50
+ function fail(sourceLabel, code, message, fieldPath) {
51
+ return makeFailure(ARTIFACT_KIND, sourceLabel, code, message, fieldPath);
52
+ }
53
+ function requireEnum(value, allowed, fieldPath, sourceLabel, errorCode) {
54
+ if (typeof value !== "string" || !allowed.includes(value)) {
55
+ return fail(sourceLabel, errorCode, `Field "${fieldPath}" must be one of: ${allowed.join(", ")}. Received: ${JSON.stringify(value)}.`, fieldPath);
56
+ }
57
+ return value;
58
+ }
59
+ function isReadinessIssue(value) {
60
+ if (!isPlainObject(value))
61
+ return false;
62
+ return (typeof value.code === "string" &&
63
+ (value.severity === "error" || value.severity === "warning") &&
64
+ typeof value.message === "string" &&
65
+ typeof value.priority === "number" &&
66
+ typeof value.correctiveAction === "string" &&
67
+ typeof value.evidenceTarget === "string" &&
68
+ typeof value.stageId === "string" &&
69
+ (value.contextKind === "implementation" || value.contextKind === "test"));
70
+ }
71
+ function isBlockerSummary(value) {
72
+ if (!isPlainObject(value))
73
+ return false;
74
+ return ((value.contextKind === "implementation" || value.contextKind === "test") &&
75
+ typeof value.primaryCode === "string" &&
76
+ typeof value.primaryReason === "string" &&
77
+ typeof value.correctiveAction === "string" &&
78
+ typeof value.evidenceTarget === "string" &&
79
+ Array.isArray(value.blockingIssueCodes) &&
80
+ value.blockingIssueCodes.every((c) => typeof c === "string") &&
81
+ Array.isArray(value.supportingIssueCodes) &&
82
+ value.supportingIssueCodes.every((c) => typeof c === "string"));
83
+ }
84
+ export function validateOrchestratorContextReadinessResultV1(input, sourceLabel) {
85
+ if (!isPlainObject(input)) {
86
+ return fail(sourceLabel, "MALFORMED_TEXT_ARTIFACT", `Readiness input at "${sourceLabel}" must be a plain object.`);
87
+ }
88
+ const schemaVersion = input["schemaVersion"];
89
+ if (typeof schemaVersion !== "string" || schemaVersion.length === 0) {
90
+ return fail(sourceLabel, "MISSING_REQUIRED_FIELD", `Readiness input at "${sourceLabel}" is missing "schemaVersion".`, "schemaVersion");
91
+ }
92
+ const kind = requireEnum(input["kind"], ["implementation", "test"], "kind", sourceLabel, "MISSING_REQUIRED_FIELD");
93
+ if (typeof kind !== "string")
94
+ return kind;
95
+ const roleAllowed = ["implementation", "test-implementation"];
96
+ const role = requireEnum(input["role"], roleAllowed, "role", sourceLabel, "MISSING_REQUIRED_FIELD");
97
+ if (typeof role !== "string")
98
+ return role;
99
+ const expectedRole = kind === "implementation" ? "implementation" : "test-implementation";
100
+ if (role !== expectedRole) {
101
+ return fail(sourceLabel, "DOCUMENT_ROLE_MISMATCH", `Readiness input at "${sourceLabel}" declares kind "${kind}" with role "${role}", but role must be "${expectedRole}" for that kind.`, "role");
102
+ }
103
+ const decision = requireEnum(input["decision"], READINESS_DECISIONS, "decision", sourceLabel, "UNKNOWN_READINESS_DECISION");
104
+ if (typeof decision !== "string")
105
+ return decision;
106
+ const classification = requireEnum(input["classification"], READINESS_CLASSIFICATIONS, "classification", sourceLabel, "INVALID_LITERAL_VALUE");
107
+ if (typeof classification !== "string")
108
+ return classification;
109
+ const stageId = input["stageId"];
110
+ if (typeof stageId !== "string" || stageId.length === 0) {
111
+ return fail(sourceLabel, "MISSING_REQUIRED_FIELD", `Readiness input at "${sourceLabel}" is missing "stageId".`, "stageId");
112
+ }
113
+ const packetPath = input["packetPath"];
114
+ const reportPath = input["reportPath"];
115
+ if (typeof packetPath !== "string" || typeof reportPath !== "string") {
116
+ return fail(sourceLabel, "MISSING_REQUIRED_FIELD", `Readiness input at "${sourceLabel}" must declare string "packetPath" and "reportPath".`);
117
+ }
118
+ const issuesRaw = input["issues"];
119
+ if (!Array.isArray(issuesRaw) || !issuesRaw.every(isReadinessIssue)) {
120
+ return fail(sourceLabel, "MALFORMED_ISSUE_STRUCTURE", `Readiness input at "${sourceLabel}" has a malformed "issues" array.`, "issues");
121
+ }
122
+ const issues = issuesRaw;
123
+ const warningsRaw = input["warnings"];
124
+ if (!Array.isArray(warningsRaw) || !warningsRaw.every((w) => typeof w === "string")) {
125
+ return fail(sourceLabel, "INVALID_FIELD_TYPE", `Readiness input at "${sourceLabel}" must declare a string array "warnings".`, "warnings");
126
+ }
127
+ const blockingIssueCodesRaw = input["blockingIssueCodes"];
128
+ if (!Array.isArray(blockingIssueCodesRaw) || !blockingIssueCodesRaw.every((c) => typeof c === "string")) {
129
+ return fail(sourceLabel, "INVALID_FIELD_TYPE", `Readiness input at "${sourceLabel}" must declare a string array "blockingIssueCodes".`, "blockingIssueCodes");
130
+ }
131
+ let primaryIssue;
132
+ if (input["primaryIssue"] !== undefined) {
133
+ if (!isReadinessIssue(input["primaryIssue"])) {
134
+ return fail(sourceLabel, "MALFORMED_ISSUE_STRUCTURE", `Readiness input at "${sourceLabel}" has a malformed "primaryIssue".`, "primaryIssue");
135
+ }
136
+ primaryIssue = input["primaryIssue"];
137
+ }
138
+ let blockerSummary;
139
+ if (input["blockerSummary"] !== undefined) {
140
+ if (!isBlockerSummary(input["blockerSummary"])) {
141
+ return fail(sourceLabel, "MALFORMED_ISSUE_STRUCTURE", `Readiness input at "${sourceLabel}" has a malformed "blockerSummary".`, "blockerSummary");
142
+ }
143
+ blockerSummary = input["blockerSummary"];
144
+ }
145
+ const affectedResponsibilityIdsRaw = input["affectedResponsibilityIds"];
146
+ if (!Array.isArray(affectedResponsibilityIdsRaw) || !affectedResponsibilityIdsRaw.every((id) => typeof id === "string")) {
147
+ return fail(sourceLabel, "INVALID_FIELD_TYPE", `Readiness input at "${sourceLabel}" must declare a string array "affectedResponsibilityIds".`, "affectedResponsibilityIds");
148
+ }
149
+ const evaluatedFreshness = requireEnum(input["evaluatedFreshness"], VALID_FRESHNESS_VALUES, "evaluatedFreshness", sourceLabel, "MISSING_REQUIRED_FIELD");
150
+ if (typeof evaluatedFreshness !== "string")
151
+ return evaluatedFreshness;
152
+ const evaluatedAdequacy = requireEnum(input["evaluatedAdequacy"], VALID_ADEQUACY_VALUES, "evaluatedAdequacy", sourceLabel, "MISSING_REQUIRED_FIELD");
153
+ if (typeof evaluatedAdequacy !== "string")
154
+ return evaluatedAdequacy;
155
+ const requiredEvidenceTruncated = requireEnum(input["requiredEvidenceTruncated"], VALID_TRUNCATION_VALUES, "requiredEvidenceTruncated", sourceLabel, "MISSING_REQUIRED_FIELD");
156
+ if (typeof requiredEvidenceTruncated !== "string")
157
+ return requiredEvidenceTruncated;
158
+ let declaredFreshness;
159
+ if (input["declaredFreshness"] !== undefined) {
160
+ const v = requireEnum(input["declaredFreshness"], VALID_FRESHNESS_VALUES, "declaredFreshness", sourceLabel, "INVALID_LITERAL_VALUE");
161
+ if (typeof v !== "string")
162
+ return v;
163
+ declaredFreshness = v;
164
+ }
165
+ let declaredAdequacy;
166
+ if (input["declaredAdequacy"] !== undefined) {
167
+ const v = requireEnum(input["declaredAdequacy"], VALID_ADEQUACY_VALUES, "declaredAdequacy", sourceLabel, "INVALID_LITERAL_VALUE");
168
+ if (typeof v !== "string")
169
+ return v;
170
+ declaredAdequacy = v;
171
+ }
172
+ let responsibilityMappingsTruncated;
173
+ if (input["responsibilityMappingsTruncated"] !== undefined) {
174
+ const v = requireEnum(input["responsibilityMappingsTruncated"], VALID_TRUNCATION_VALUES, "responsibilityMappingsTruncated", sourceLabel, "INVALID_LITERAL_VALUE");
175
+ if (typeof v !== "string")
176
+ return v;
177
+ responsibilityMappingsTruncated = v;
178
+ }
179
+ const readyWithAssumptions = input["readyWithAssumptions"];
180
+ if (typeof readyWithAssumptions !== "boolean") {
181
+ return fail(sourceLabel, "INVALID_FIELD_TYPE", `Readiness input at "${sourceLabel}" must declare boolean "readyWithAssumptions".`, "readyWithAssumptions");
182
+ }
183
+ const provenanceSummary = input["provenanceSummary"];
184
+ if (typeof provenanceSummary !== "string") {
185
+ return fail(sourceLabel, "MISSING_REQUIRED_FIELD", `Readiness input at "${sourceLabel}" is missing string "provenanceSummary".`, "provenanceSummary");
186
+ }
187
+ const indexIdentity = input["indexIdentity"];
188
+ if (indexIdentity !== undefined && (typeof indexIdentity !== "string" || indexIdentity.length === 0)) {
189
+ return fail(sourceLabel, "MISSING_CANONICAL_IDENTITY", `Readiness input at "${sourceLabel}" declares a non-string or empty "indexIdentity".`, "indexIdentity");
190
+ }
191
+ const sourceCapsulePath = input["sourceCapsulePath"];
192
+ const sourceAuditPath = input["sourceAuditPath"];
193
+ if (sourceCapsulePath !== undefined && typeof sourceCapsulePath !== "string") {
194
+ return fail(sourceLabel, "INVALID_FIELD_TYPE", `Readiness input at "${sourceLabel}" has non-string "sourceCapsulePath".`, "sourceCapsulePath");
195
+ }
196
+ if (sourceAuditPath !== undefined && typeof sourceAuditPath !== "string") {
197
+ return fail(sourceLabel, "INVALID_FIELD_TYPE", `Readiness input at "${sourceLabel}" has non-string "sourceAuditPath".`, "sourceAuditPath");
198
+ }
199
+ const artifact = {
200
+ schemaVersion,
201
+ kind,
202
+ role,
203
+ decision,
204
+ classification,
205
+ stageId,
206
+ packetPath,
207
+ reportPath,
208
+ sourceCapsulePath: sourceCapsulePath,
209
+ sourceAuditPath: sourceAuditPath,
210
+ issues,
211
+ warnings: warningsRaw,
212
+ blockingIssueCodes: blockingIssueCodesRaw,
213
+ primaryIssue,
214
+ blockerSummary,
215
+ affectedResponsibilityIds: affectedResponsibilityIdsRaw,
216
+ declaredFreshness,
217
+ evaluatedFreshness,
218
+ declaredAdequacy,
219
+ evaluatedAdequacy,
220
+ requiredEvidenceTruncated,
221
+ responsibilityMappingsTruncated,
222
+ indexIdentity: indexIdentity,
223
+ readyWithAssumptions,
224
+ provenanceSummary
225
+ };
226
+ return {
227
+ ok: true,
228
+ artifactKind: ARTIFACT_KIND,
229
+ sourcePath: sourceLabel,
230
+ schemaVersion,
231
+ schemaMajor: 1,
232
+ artifact,
233
+ rawArtifact: input
234
+ };
235
+ }
236
+ export function checkSupplementalReadinessIdentityConsistency(document, readiness) {
237
+ if (readiness.indexIdentity === undefined)
238
+ return null;
239
+ if (document.indexIdentity === readiness.indexIdentity)
240
+ return null;
241
+ return {
242
+ code: "INCOMPATIBLE_ARTIFACT_IDENTITY",
243
+ message: `Supplemental document index identity "${document.indexIdentity}" does not match readiness result index identity "${readiness.indexIdentity}".`,
244
+ documentIndexIdentity: document.indexIdentity,
245
+ readinessIndexIdentity: readiness.indexIdentity
246
+ };
247
+ }
@@ -0,0 +1,9 @@
1
+ import { readTextArtifactFile } from "./readSupplementalContextTextFile.js";
2
+ import { validateSupplementalContextDocumentV1 } from "./validateSupplementalContextDocumentV1.js";
3
+ const ARTIFACT_KIND = "orchestrator-implementation-context-packet-v1";
4
+ export async function readImplementationContextPacketV1(sourcePath) {
5
+ const loaded = await readTextArtifactFile(ARTIFACT_KIND, sourcePath);
6
+ if (!loaded.ok)
7
+ return loaded;
8
+ return validateSupplementalContextDocumentV1(ARTIFACT_KIND, "implementation-context-packet", loaded.text, loaded.sourcePath);
9
+ }
@@ -0,0 +1,9 @@
1
+ import { readTextArtifactFile } from "./readSupplementalContextTextFile.js";
2
+ import { validateSupplementalContextDocumentV1 } from "./validateSupplementalContextDocumentV1.js";
3
+ const ARTIFACT_KIND = "orchestrator-implementation-context-retrieval-report-v1";
4
+ export async function readImplementationContextRetrievalReportV1(sourcePath) {
5
+ const loaded = await readTextArtifactFile(ARTIFACT_KIND, sourcePath);
6
+ if (!loaded.ok)
7
+ return loaded;
8
+ return validateSupplementalContextDocumentV1(ARTIFACT_KIND, "implementation-context-retrieval-report", loaded.text, loaded.sourcePath);
9
+ }
@@ -0,0 +1,29 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ export async function readTextArtifactFile(artifactKind, sourcePathInput) {
4
+ const sourcePath = path.resolve(sourcePathInput);
5
+ let text;
6
+ try {
7
+ text = await readFile(sourcePath, "utf8");
8
+ }
9
+ catch (error) {
10
+ const code = error.code;
11
+ if (code === "ENOENT") {
12
+ return {
13
+ ok: false,
14
+ artifactKind,
15
+ sourcePath,
16
+ code: "FILE_NOT_FOUND",
17
+ message: `Artifact "${artifactKind}" file was not found at "${sourcePath}".`
18
+ };
19
+ }
20
+ return {
21
+ ok: false,
22
+ artifactKind,
23
+ sourcePath,
24
+ code: "UNREADABLE_FILE",
25
+ message: `Artifact "${artifactKind}" file at "${sourcePath}" could not be read: ${error.message}`
26
+ };
27
+ }
28
+ return { ok: true, sourcePath, text };
29
+ }
@@ -0,0 +1,9 @@
1
+ import { readTextArtifactFile } from "./readSupplementalContextTextFile.js";
2
+ import { validateSupplementalContextDocumentV1 } from "./validateSupplementalContextDocumentV1.js";
3
+ const ARTIFACT_KIND = "orchestrator-test-context-packet-v1";
4
+ export async function readTestContextPacketV1(sourcePath) {
5
+ const loaded = await readTextArtifactFile(ARTIFACT_KIND, sourcePath);
6
+ if (!loaded.ok)
7
+ return loaded;
8
+ return validateSupplementalContextDocumentV1(ARTIFACT_KIND, "test-context-packet", loaded.text, loaded.sourcePath);
9
+ }
@@ -0,0 +1,9 @@
1
+ import { readTextArtifactFile } from "./readSupplementalContextTextFile.js";
2
+ import { validateSupplementalContextDocumentV1 } from "./validateSupplementalContextDocumentV1.js";
3
+ const ARTIFACT_KIND = "orchestrator-test-context-retrieval-report-v1";
4
+ export async function readTestContextRetrievalReportV1(sourcePath) {
5
+ const loaded = await readTextArtifactFile(ARTIFACT_KIND, sourcePath);
6
+ if (!loaded.ok)
7
+ return loaded;
8
+ return validateSupplementalContextDocumentV1(ARTIFACT_KIND, "test-context-retrieval-report", loaded.text, loaded.sourcePath);
9
+ }
@@ -0,0 +1,75 @@
1
+ // Deterministic line-based parser for the frozen my-dev-kit-orchestrator supplemental
2
+ // repository-context document format (commit bc08a05d3b52a629e7e4504372af199c324c4ae4,
3
+ // src/instructions/supplementalContextParser.ts): "Key: value" metadata lines before the
4
+ // first "## " heading, then "## Heading" sections running to the next heading or EOF.
5
+ // Independently re-derived from the frozen contract for the lab's own read-only boundary;
6
+ // never imports orchestrator runtime code. Structural classification only -- never
7
+ // evaluates whether a declared value is true.
8
+ const METADATA_LINE_RE = /^([A-Za-z][A-Za-z0-9 -]*): (.*)$/;
9
+ const SECTION_HEADING_RE = /^## (.+)$/;
10
+ export function parseSupplementalContextText(text) {
11
+ const lines = text.split(/\r\n|\n/);
12
+ const metadata = {};
13
+ const metadataOrder = [];
14
+ const duplicateMetadataKeys = [];
15
+ const emptyMetadataKeys = [];
16
+ let i = 0;
17
+ for (; i < lines.length; i++) {
18
+ const line = lines[i];
19
+ if (SECTION_HEADING_RE.test(line))
20
+ break;
21
+ const match = line.match(METADATA_LINE_RE);
22
+ if (!match)
23
+ continue;
24
+ const key = match[1];
25
+ const value = match[2].trim();
26
+ if (Object.prototype.hasOwnProperty.call(metadata, key)) {
27
+ duplicateMetadataKeys.push(key);
28
+ continue;
29
+ }
30
+ if (value.length === 0) {
31
+ emptyMetadataKeys.push(key);
32
+ }
33
+ metadata[key] = value;
34
+ metadataOrder.push(key);
35
+ }
36
+ const sections = {};
37
+ const sectionOrder = [];
38
+ const duplicateSectionHeadings = [];
39
+ let currentHeading = null;
40
+ let currentLines = [];
41
+ const flush = () => {
42
+ if (currentHeading === null)
43
+ return;
44
+ const content = currentLines.join("\n").trim();
45
+ if (Object.prototype.hasOwnProperty.call(sections, currentHeading)) {
46
+ duplicateSectionHeadings.push(currentHeading);
47
+ }
48
+ else {
49
+ sections[currentHeading] = content;
50
+ sectionOrder.push(currentHeading);
51
+ }
52
+ };
53
+ for (; i < lines.length; i++) {
54
+ const line = lines[i];
55
+ const headingMatch = line.match(SECTION_HEADING_RE);
56
+ if (headingMatch) {
57
+ flush();
58
+ currentHeading = headingMatch[1].trim();
59
+ currentLines = [];
60
+ }
61
+ else if (currentHeading !== null) {
62
+ currentLines.push(line);
63
+ }
64
+ }
65
+ flush();
66
+ return {
67
+ metadata,
68
+ metadataOrder,
69
+ sections,
70
+ sectionOrder,
71
+ duplicateMetadataKeys,
72
+ emptyMetadataKeys,
73
+ duplicateSectionHeadings
74
+ };
75
+ }
@@ -0,0 +1,152 @@
1
+ // Lab-owned structural mirror of the frozen my-dev-kit-orchestrator supplemental
2
+ // repository-context document vocabulary (commit bc08a05d3b52a629e7e4504372af199c324c4ae4,
3
+ // src/instructions/supplementalContextTypes.ts). The lab never imports orchestrator
4
+ // runtime code; this file only restates the frozen vocabulary needed to validate and
5
+ // preserve documents the orchestrator already writes.
6
+ export const SUPPLEMENTAL_CONTEXT_PACKET_SCHEMA_SUPPORTED_MAJOR = 1;
7
+ export const SUPPLEMENTAL_CONTEXT_RETRIEVAL_REPORT_SCHEMA_SUPPORTED_MAJOR = 1;
8
+ export const ROLE_BY_DOCUMENT_KIND = {
9
+ "implementation-context-packet": "implementation",
10
+ "implementation-context-retrieval-report": "implementation",
11
+ "test-context-packet": "test-implementation",
12
+ "test-context-retrieval-report": "test-implementation"
13
+ };
14
+ export function isRetrievalReportKind(kind) {
15
+ return kind === "implementation-context-retrieval-report" || kind === "test-context-retrieval-report";
16
+ }
17
+ export function isTestKind(kind) {
18
+ return kind === "test-context-packet" || kind === "test-context-retrieval-report";
19
+ }
20
+ const COMMON_PACKET_METADATA = [
21
+ "Schema version",
22
+ "Document kind",
23
+ "Role",
24
+ "Status",
25
+ "Repository scope",
26
+ "Freshness",
27
+ "Adequacy",
28
+ "Required evidence truncated",
29
+ "Context capsule schema version",
30
+ "Retrieval audit schema version",
31
+ "Tool name",
32
+ "Tool version",
33
+ "Index identity"
34
+ ];
35
+ const COMMON_REPORT_METADATA = [
36
+ "Schema version",
37
+ "Document kind",
38
+ "Role",
39
+ "Status",
40
+ "Repository scope",
41
+ "Request schema version",
42
+ "Context capsule schema version",
43
+ "Retrieval audit schema version",
44
+ "Tool name",
45
+ "Tool version",
46
+ "Index identity",
47
+ "Freshness",
48
+ "Adequacy",
49
+ "Required evidence truncated",
50
+ "Full-file fallback used",
51
+ "Determinism checked"
52
+ ];
53
+ const TEST_ONLY_METADATA = ["Responsibility mappings truncated", "Critical responsibility mapping status"];
54
+ export const REQUIRED_METADATA_BY_DOCUMENT_KIND = {
55
+ "implementation-context-packet": COMMON_PACKET_METADATA,
56
+ "implementation-context-retrieval-report": COMMON_REPORT_METADATA,
57
+ "test-context-packet": [...COMMON_PACKET_METADATA, ...TEST_ONLY_METADATA],
58
+ "test-context-retrieval-report": [...COMMON_REPORT_METADATA, ...TEST_ONLY_METADATA]
59
+ };
60
+ export const REQUIRED_SECTIONS_BY_DOCUMENT_KIND = {
61
+ "implementation-context-packet": [
62
+ "Focus",
63
+ "Selected owners",
64
+ "Dependencies",
65
+ "Contracts",
66
+ "Validators",
67
+ "Constants",
68
+ "Errors",
69
+ "Schemas",
70
+ "Callers and callees",
71
+ "Closest tests",
72
+ "Test infrastructure",
73
+ "Test commands",
74
+ "Unresolved items",
75
+ "Budget and truncation",
76
+ "Full-file fallback",
77
+ "Provenance",
78
+ "Assumptions",
79
+ "Notes"
80
+ ],
81
+ "implementation-context-retrieval-report": [
82
+ "Retrieval request",
83
+ "Command record",
84
+ "Focus selection",
85
+ "Candidate and owner selection",
86
+ "Evidence groups",
87
+ "Unresolved evidence",
88
+ "Adequacy evaluation",
89
+ "Freshness classification",
90
+ "Budget",
91
+ "Truncation",
92
+ "Full-file fallback",
93
+ "Provenance",
94
+ "Warnings",
95
+ "Determinism",
96
+ "Assumptions",
97
+ "Notes"
98
+ ],
99
+ "test-context-packet": [
100
+ "Changed surface",
101
+ "Production owners",
102
+ "Production contracts",
103
+ "Validators",
104
+ "Constants",
105
+ "Errors",
106
+ "Schemas",
107
+ "Closest tests",
108
+ "Test infrastructure",
109
+ "Test commands",
110
+ "Test responsibilities",
111
+ "Responsibility mappings",
112
+ "Reusable test helpers",
113
+ "Oracle evidence",
114
+ "Unresolved items",
115
+ "Budget and truncation",
116
+ "Full-file fallback",
117
+ "Provenance",
118
+ "Assumptions",
119
+ "Notes"
120
+ ],
121
+ "test-context-retrieval-report": [
122
+ "Retrieval request",
123
+ "Command record",
124
+ "Changed-surface selection",
125
+ "Production-owner selection",
126
+ "Test-infrastructure discovery",
127
+ "Test-command discovery",
128
+ "Responsibility mapping",
129
+ "Criticality overlay",
130
+ "Adequacy evaluation",
131
+ "Freshness classification",
132
+ "Budget",
133
+ "Truncation",
134
+ "Full-file fallback",
135
+ "Provenance",
136
+ "Warnings",
137
+ "Determinism",
138
+ "Assumptions",
139
+ "Notes"
140
+ ]
141
+ };
142
+ export const VALID_REPOSITORY_SCOPES = ["single-repository", "source-target"];
143
+ export const VALID_DECLARED_STATUSES = ["template", "populated"];
144
+ export const VALID_FRESHNESS_VALUES = ["fresh", "stale", "unknown"];
145
+ export const VALID_ADEQUACY_VALUES = [
146
+ "sufficient",
147
+ "sufficient-with-assumptions",
148
+ "insufficient",
149
+ "conflict",
150
+ "unknown"
151
+ ];
152
+ export const VALID_TRUNCATION_VALUES = ["yes", "no", "unknown"];
@@ -1,5 +1,5 @@
1
1
  import { parseSupportedMajorOneSchemaVersion } from "./schemaVersion.js";
2
- import { ArtifactValidationError, arrayFieldPath, joinFieldPath, requiredArray, requiredField, requiredLiteral, requiredObject, requiredRecord, requiredScalarLike, requiredString, requiredStringArray } from "./runtimeValidation.js";
2
+ import { ArtifactValidationError, arrayFieldPath, joinFieldPath, optionalField, optionalString, requiredArray, requiredField, requiredLiteral, requiredObject, requiredRecord, requiredScalarLike, requiredString, requiredStringArray } from "./runtimeValidation.js";
3
3
  import { validateBudgetSummary, validateContextAdequacyStatement, validateContextCapsuleRequest, validateFreshnessSummary, validateFullFileFallbackSummary, validateProvenanceRecord, validateResponsibilityMappingSummary, validateRoleAdequacyStatement, validateRoleContextSummary, validateTruncationSummary } from "./validateMyDevKitContextCapsuleV1.js";
4
4
  const ARTIFACT_KIND = "my-dev-kit-retrieval-audit-record-v1";
5
5
  const AUDIT_STEP_STATUSES = ["ok", "skipped", "failed"];
@@ -12,10 +12,17 @@ function validateContextCapsuleTool(ctx, value, fieldPath) {
12
12
  }
13
13
  function validateRetrievalAuditRecordIndex(ctx, value, fieldPath) {
14
14
  const obj = requiredObject(ctx, value, fieldPath);
15
- return {
15
+ const result = {
16
16
  indexPath: requiredString(ctx, requiredField(ctx, obj, "indexPath", joinFieldPath(fieldPath, "indexPath")), joinFieldPath(fieldPath, "indexPath")),
17
17
  manifestPath: requiredString(ctx, requiredField(ctx, obj, "manifestPath", joinFieldPath(fieldPath, "manifestPath")), joinFieldPath(fieldPath, "manifestPath"))
18
18
  };
19
+ if (optionalField(obj, "manifestSchemaVersion") !== undefined) {
20
+ result.manifestSchemaVersion = optionalString(ctx, obj.manifestSchemaVersion, joinFieldPath(fieldPath, "manifestSchemaVersion"));
21
+ }
22
+ if (optionalField(obj, "projectRoot") !== undefined) {
23
+ result.projectRoot = optionalString(ctx, obj.projectRoot, joinFieldPath(fieldPath, "projectRoot"));
24
+ }
25
+ return result;
19
26
  }
20
27
  function validateAuditStepRecord(ctx, value, fieldPath) {
21
28
  const obj = requiredRecord(ctx, value, fieldPath);