@danmoisan/drm-copilot-mcp 1.1.17 → 1.1.18
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/out/mcp-server.js +500 -106
- package/package.json +4 -3
- package/resources/claude-customizations/.claude/agents/feature-review.md +10 -1
- package/resources/claude-customizations/.claude/agents/orchestrator.md +16 -3
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +6 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-lane-assertion.sh +4 -2
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorState.psm1 +6 -13
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +375 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateReceipts.psm1 +22 -15
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRemediationAccounting.psm1 +337 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRoutingContract.psm1 +9 -1
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +119 -3
- package/resources/claude-customizations/.claude/rules/quality-tiers.md +1 -1
- package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +8 -0
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +2 -0
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +11 -3
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup-worktrees.sh +11 -2
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_enumerate_lib.sh +169 -5
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_lib.sh +1 -1
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_report_records_lib.sh +6 -43
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_scan_helper.sh +4 -15
- package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +13 -6
- package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +4 -0
- package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +10 -0
- package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +3 -1
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +30 -12
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +18 -3
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +5 -1
- package/resources/claude-customizations/pack-manifests/core.json +2 -0
- package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +8 -0
- package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +5 -3
- package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +4 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-promotion-lifecycle/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +30 -6
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +3 -1
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +30 -7
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-state/SKILL.md +41 -2
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +18 -3
- package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +2 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c1.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c2.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3-elevated.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c4.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +8 -0
- package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +4 -0
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +4 -0
package/out/mcp-server.js
CHANGED
|
@@ -4150,13 +4150,14 @@ var require_fast_uri = __commonJS({
|
|
|
4150
4150
|
if (!malformedIPLiteral) {
|
|
4151
4151
|
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
4152
4152
|
}
|
|
4153
|
-
if (
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
4158
|
-
}
|
|
4153
|
+
if (uri.indexOf("%") !== -1 && parsed.host !== void 0 && !malformedIPLiteral) {
|
|
4154
|
+
let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
4155
|
+
if (!isIP) {
|
|
4156
|
+
host = normalizePercentEncoding(host.toLowerCase());
|
|
4159
4157
|
}
|
|
4158
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
4159
|
+
}
|
|
4160
|
+
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
4160
4161
|
if (parsed.path) {
|
|
4161
4162
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
4162
4163
|
}
|
|
@@ -9273,13 +9274,13 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
9273
9274
|
}
|
|
9274
9275
|
return propValues;
|
|
9275
9276
|
});
|
|
9276
|
-
const
|
|
9277
|
+
const isObject16 = isObject;
|
|
9277
9278
|
const catchall = def.catchall;
|
|
9278
9279
|
let value;
|
|
9279
9280
|
inst._zod.parse = (payload, ctx) => {
|
|
9280
9281
|
value ?? (value = _normalized.value);
|
|
9281
9282
|
const input = payload.value;
|
|
9282
|
-
if (!
|
|
9283
|
+
if (!isObject16(input)) {
|
|
9283
9284
|
payload.issues.push({
|
|
9284
9285
|
expected: "object",
|
|
9285
9286
|
code: "invalid_type",
|
|
@@ -9406,7 +9407,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
9406
9407
|
return (payload, ctx) => fn(shape, payload, ctx);
|
|
9407
9408
|
};
|
|
9408
9409
|
let fastpass;
|
|
9409
|
-
const
|
|
9410
|
+
const isObject16 = isObject;
|
|
9410
9411
|
const jit = !globalConfig.jitless;
|
|
9411
9412
|
const allowsEval2 = allowsEval;
|
|
9412
9413
|
const fastEnabled = jit && allowsEval2.value;
|
|
@@ -9415,7 +9416,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
9415
9416
|
inst._zod.parse = (payload, ctx) => {
|
|
9416
9417
|
value ?? (value = _normalized.value);
|
|
9417
9418
|
const input = payload.value;
|
|
9418
|
-
if (!
|
|
9419
|
+
if (!isObject16(input)) {
|
|
9419
9420
|
payload.issues.push({
|
|
9420
9421
|
expected: "object",
|
|
9421
9422
|
code: "invalid_type",
|
|
@@ -25739,6 +25740,7 @@ var MERGED_STATUSES = /* @__PURE__ */ new Set([
|
|
|
25739
25740
|
"merged",
|
|
25740
25741
|
"worktree_removed"
|
|
25741
25742
|
]);
|
|
25743
|
+
var NOT_STARTED_MERGE_STATUS = "not_started";
|
|
25742
25744
|
function isObject6(value) {
|
|
25743
25745
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25744
25746
|
}
|
|
@@ -25819,6 +25821,9 @@ function validateMergeStatusEnum(features) {
|
|
|
25819
25821
|
}
|
|
25820
25822
|
return errors;
|
|
25821
25823
|
}
|
|
25824
|
+
function hasStarted(feature) {
|
|
25825
|
+
return typeof feature["worktree_created_at"] === "string" || feature["merge_status"] !== NOT_STARTED_MERGE_STATUS;
|
|
25826
|
+
}
|
|
25822
25827
|
function validateWaveBarrierOrdering(features) {
|
|
25823
25828
|
const errors = [];
|
|
25824
25829
|
const byFolder = /* @__PURE__ */ new Map();
|
|
@@ -25835,6 +25840,9 @@ function validateWaveBarrierOrdering(features) {
|
|
|
25835
25840
|
if (typeof folder !== "string" || !Array.isArray(dependsOn)) {
|
|
25836
25841
|
continue;
|
|
25837
25842
|
}
|
|
25843
|
+
if (!hasStarted(feature)) {
|
|
25844
|
+
continue;
|
|
25845
|
+
}
|
|
25838
25846
|
const worktreeCreatedAt = feature["worktree_created_at"];
|
|
25839
25847
|
for (const dependency of dependsOn) {
|
|
25840
25848
|
const resolved = resolveFeatureReference(dependency, index);
|
|
@@ -25846,9 +25854,13 @@ function validateWaveBarrierOrdering(features) {
|
|
|
25846
25854
|
const depConfirmedAt = dependencyFeature["merge_confirmed_at"];
|
|
25847
25855
|
const statusViolation = typeof depMergeStatus !== "string" || !MERGED_STATUSES.has(depMergeStatus);
|
|
25848
25856
|
const timingViolation = typeof depConfirmedAt === "string" && typeof worktreeCreatedAt === "string" && depConfirmedAt > worktreeCreatedAt;
|
|
25849
|
-
if (statusViolation
|
|
25857
|
+
if (statusViolation) {
|
|
25858
|
+
errors.push(
|
|
25859
|
+
`EPIC_WAVE_BARRIER_VIOLATION: ${folder} is treated as started while dependency ${String(dependency)} is not merged`
|
|
25860
|
+
);
|
|
25861
|
+
} else if (timingViolation) {
|
|
25850
25862
|
errors.push(
|
|
25851
|
-
`EPIC_WAVE_BARRIER_VIOLATION: ${folder}
|
|
25863
|
+
`EPIC_WAVE_BARRIER_VIOLATION: ${folder} worktree_created_at precedes dependency ${String(dependency)} merge_confirmed_at`
|
|
25852
25864
|
);
|
|
25853
25865
|
}
|
|
25854
25866
|
}
|
|
@@ -27194,6 +27206,201 @@ function validateEpicPlannerStateText(text2, options = {}) {
|
|
|
27194
27206
|
return errors;
|
|
27195
27207
|
}
|
|
27196
27208
|
|
|
27209
|
+
// ../../extensions/drm-copilot/src/lib/validate/orchestrator-state-blocked-reason.ts
|
|
27210
|
+
var MECHANICAL_BLOCKED_REASONS = /* @__PURE__ */ new Set([
|
|
27211
|
+
"spawn_agent_unavailable",
|
|
27212
|
+
"delegation_launch_failed",
|
|
27213
|
+
"delegate_no_receipt",
|
|
27214
|
+
"delegate_contract_incomplete",
|
|
27215
|
+
"validator_failed",
|
|
27216
|
+
"user_requested_stop"
|
|
27217
|
+
]);
|
|
27218
|
+
var NON_MECHANICAL_BLOCKED_REASONS = /* @__PURE__ */ new Set([
|
|
27219
|
+
"premise_falsified",
|
|
27220
|
+
"external_dependency",
|
|
27221
|
+
"policy_hold",
|
|
27222
|
+
"awaiting_ci",
|
|
27223
|
+
"human_decision_required"
|
|
27224
|
+
]);
|
|
27225
|
+
var VALID_BLOCKED_REASONS = /* @__PURE__ */ new Set([
|
|
27226
|
+
"none",
|
|
27227
|
+
...MECHANICAL_BLOCKED_REASONS,
|
|
27228
|
+
...NON_MECHANICAL_BLOCKED_REASONS
|
|
27229
|
+
]);
|
|
27230
|
+
|
|
27231
|
+
// ../../extensions/drm-copilot/src/lib/validate/orchestrator-state-promotion-tools.ts
|
|
27232
|
+
var FEATURE_PROMOTION_ENTRY_TOOL = "new_potential_entry";
|
|
27233
|
+
var BUG_PROMOTION_ENTRY_TOOL = "new_potential_bug_entry";
|
|
27234
|
+
var BUG_PROMOTION_TYPE = "bug";
|
|
27235
|
+
var PROMOTION_TYPE_KEY = "promotion-type";
|
|
27236
|
+
function resolvePromotionEntryTools(requiredMcpTools, state) {
|
|
27237
|
+
if (state[PROMOTION_TYPE_KEY] !== BUG_PROMOTION_TYPE) {
|
|
27238
|
+
return [...requiredMcpTools];
|
|
27239
|
+
}
|
|
27240
|
+
return requiredMcpTools.map(
|
|
27241
|
+
(tool) => tool === FEATURE_PROMOTION_ENTRY_TOOL ? BUG_PROMOTION_ENTRY_TOOL : tool
|
|
27242
|
+
);
|
|
27243
|
+
}
|
|
27244
|
+
|
|
27245
|
+
// ../../extensions/drm-copilot/src/lib/validate/orchestrator-state-issue-adoption.ts
|
|
27246
|
+
var ISSUE_ADOPTION_KEY = "issue_adoption";
|
|
27247
|
+
var POTENTIAL_TO_ISSUE_TOOL = "potential_to_issue";
|
|
27248
|
+
var ORIGIN_VALUES = /* @__PURE__ */ new Set([
|
|
27249
|
+
"transferred",
|
|
27250
|
+
"filed_before_orchestration",
|
|
27251
|
+
"epic_decomposition"
|
|
27252
|
+
]);
|
|
27253
|
+
var VERIFIED_VIA_VALUES = /* @__PURE__ */ new Set([
|
|
27254
|
+
"gh_issue_view",
|
|
27255
|
+
"gh_api_get",
|
|
27256
|
+
"github_mcp_issue_read"
|
|
27257
|
+
]);
|
|
27258
|
+
var WAIVABLE_TOOLS = /* @__PURE__ */ new Set([
|
|
27259
|
+
POTENTIAL_TO_ISSUE_TOOL,
|
|
27260
|
+
FEATURE_PROMOTION_ENTRY_TOOL,
|
|
27261
|
+
BUG_PROMOTION_ENTRY_TOOL
|
|
27262
|
+
]);
|
|
27263
|
+
var PROMOTION_ENTRY_TOOLS = /* @__PURE__ */ new Set([
|
|
27264
|
+
FEATURE_PROMOTION_ENTRY_TOOL,
|
|
27265
|
+
BUG_PROMOTION_ENTRY_TOOL
|
|
27266
|
+
]);
|
|
27267
|
+
var POTENTIAL_RECORD_PREFIX = "docs/features/potential/";
|
|
27268
|
+
var POTENTIAL_RECORD_SUFFIX = ".md";
|
|
27269
|
+
var ISSUE_NUM_PATTERN = /^[1-9][0-9]*$/;
|
|
27270
|
+
var ERROR_NOT_OBJECT = "Checkpoint issue_adoption must be an object when present.";
|
|
27271
|
+
var ERROR_ISSUE_NUM_FORMAT = "Checkpoint issue_adoption.issue_num must be a string of decimal digits without a leading zero.";
|
|
27272
|
+
var ERROR_ISSUE_NUM_MISMATCH = "Checkpoint issue_adoption.issue_num must equal the checkpoint issue-num.";
|
|
27273
|
+
var ERROR_ISSUE_URL = "Checkpoint issue_adoption.issue_url must end with /issues/ followed by issue_num.";
|
|
27274
|
+
var ERROR_ORIGIN = "Checkpoint issue_adoption.origin must be one of transferred, filed_before_orchestration, epic_decomposition.";
|
|
27275
|
+
var ERROR_VERIFIED_VIA = "Checkpoint issue_adoption.verified_via must be one of gh_issue_view, gh_api_get, github_mcp_issue_read.";
|
|
27276
|
+
var ERROR_VERIFIED_AT = "Checkpoint issue_adoption.verified_at must be present.";
|
|
27277
|
+
var ERROR_EVIDENCE = "Checkpoint issue_adoption.evidence must be a non-empty string.";
|
|
27278
|
+
var ERROR_WAIVED_TOOLS_SHAPE = "Checkpoint issue_adoption.waived_tools must be a non-empty list of tool names.";
|
|
27279
|
+
var ERROR_WAIVED_TOOLS_INCLUDE = "Checkpoint issue_adoption.waived_tools must include potential_to_issue.";
|
|
27280
|
+
function isPlainObject3(value) {
|
|
27281
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27282
|
+
}
|
|
27283
|
+
function isNonBlankString(value) {
|
|
27284
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
27285
|
+
}
|
|
27286
|
+
function validIssueNum(value) {
|
|
27287
|
+
return typeof value === "string" && ISSUE_NUM_PATTERN.test(value) ? value : null;
|
|
27288
|
+
}
|
|
27289
|
+
function issueIdentityErrors(adoption, state) {
|
|
27290
|
+
const errors = [];
|
|
27291
|
+
const issueNum = validIssueNum(adoption["issue_num"]);
|
|
27292
|
+
if (issueNum === null) {
|
|
27293
|
+
errors.push(ERROR_ISSUE_NUM_FORMAT);
|
|
27294
|
+
} else {
|
|
27295
|
+
const checkpointIssueNum = state["issue-num"];
|
|
27296
|
+
if (typeof checkpointIssueNum === "string" && checkpointIssueNum !== issueNum) {
|
|
27297
|
+
errors.push(ERROR_ISSUE_NUM_MISMATCH);
|
|
27298
|
+
}
|
|
27299
|
+
}
|
|
27300
|
+
const issueUrl = adoption["issue_url"];
|
|
27301
|
+
if (issueNum === null || typeof issueUrl !== "string" || !issueUrl.endsWith(`/issues/${issueNum}`)) {
|
|
27302
|
+
errors.push(ERROR_ISSUE_URL);
|
|
27303
|
+
}
|
|
27304
|
+
return errors;
|
|
27305
|
+
}
|
|
27306
|
+
function provenanceErrors(adoption) {
|
|
27307
|
+
const errors = [];
|
|
27308
|
+
const origin = adoption["origin"];
|
|
27309
|
+
if (typeof origin !== "string" || !ORIGIN_VALUES.has(origin)) {
|
|
27310
|
+
errors.push(ERROR_ORIGIN);
|
|
27311
|
+
}
|
|
27312
|
+
const verifiedVia = adoption["verified_via"];
|
|
27313
|
+
if (typeof verifiedVia !== "string" || !VERIFIED_VIA_VALUES.has(verifiedVia)) {
|
|
27314
|
+
errors.push(ERROR_VERIFIED_VIA);
|
|
27315
|
+
}
|
|
27316
|
+
const verifiedAt = adoption["verified_at"];
|
|
27317
|
+
if (verifiedAt === void 0 || verifiedAt === null || typeof verifiedAt === "string" && verifiedAt.trim().length === 0) {
|
|
27318
|
+
errors.push(ERROR_VERIFIED_AT);
|
|
27319
|
+
}
|
|
27320
|
+
if (!isNonBlankString(adoption["evidence"])) {
|
|
27321
|
+
errors.push(ERROR_EVIDENCE);
|
|
27322
|
+
}
|
|
27323
|
+
return errors;
|
|
27324
|
+
}
|
|
27325
|
+
function waivedToolList(value) {
|
|
27326
|
+
if (!Array.isArray(value)) {
|
|
27327
|
+
return null;
|
|
27328
|
+
}
|
|
27329
|
+
const items = value;
|
|
27330
|
+
if (items.length === 0 || !items.every((item) => isNonBlankString(item))) {
|
|
27331
|
+
return null;
|
|
27332
|
+
}
|
|
27333
|
+
return items;
|
|
27334
|
+
}
|
|
27335
|
+
function waivedToolErrors(waived, options) {
|
|
27336
|
+
const errors = [];
|
|
27337
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27338
|
+
for (const tool of waived) {
|
|
27339
|
+
if (seen.has(tool)) {
|
|
27340
|
+
errors.push(
|
|
27341
|
+
`Checkpoint issue_adoption.waived_tools lists a tool more than once: ${tool}.`
|
|
27342
|
+
);
|
|
27343
|
+
} else if (!WAIVABLE_TOOLS.has(tool)) {
|
|
27344
|
+
errors.push(
|
|
27345
|
+
`Checkpoint issue_adoption.waived_tools names a tool that cannot be waived: ${tool}.`
|
|
27346
|
+
);
|
|
27347
|
+
} else if (!options.requiredMcpTools.includes(tool)) {
|
|
27348
|
+
errors.push(
|
|
27349
|
+
`Checkpoint issue_adoption.waived_tools names a tool that is not required by route ${options.routeId}: ${tool}.`
|
|
27350
|
+
);
|
|
27351
|
+
} else if (options.successfulTools.has(tool)) {
|
|
27352
|
+
errors.push(
|
|
27353
|
+
`Checkpoint issue_adoption.waived_tools names a tool that has a successful MCP receipt: ${tool}.`
|
|
27354
|
+
);
|
|
27355
|
+
}
|
|
27356
|
+
seen.add(tool);
|
|
27357
|
+
}
|
|
27358
|
+
if (!seen.has(POTENTIAL_TO_ISSUE_TOOL)) {
|
|
27359
|
+
errors.push(ERROR_WAIVED_TOOLS_INCLUDE);
|
|
27360
|
+
}
|
|
27361
|
+
return errors;
|
|
27362
|
+
}
|
|
27363
|
+
function potentialRecordErrors(waived, potentialRecord) {
|
|
27364
|
+
if (typeof potentialRecord === "string" && potentialRecord.startsWith(POTENTIAL_RECORD_PREFIX) && potentialRecord.endsWith(POTENTIAL_RECORD_SUFFIX)) {
|
|
27365
|
+
return [];
|
|
27366
|
+
}
|
|
27367
|
+
const errors = [];
|
|
27368
|
+
const reported = /* @__PURE__ */ new Set();
|
|
27369
|
+
for (const tool of waived) {
|
|
27370
|
+
if (PROMOTION_ENTRY_TOOLS.has(tool) && !reported.has(tool)) {
|
|
27371
|
+
errors.push(
|
|
27372
|
+
`Checkpoint issue_adoption.potential_record must name a markdown file under docs/features/potential/ when waiving ${tool}.`
|
|
27373
|
+
);
|
|
27374
|
+
reported.add(tool);
|
|
27375
|
+
}
|
|
27376
|
+
}
|
|
27377
|
+
return errors;
|
|
27378
|
+
}
|
|
27379
|
+
function resolveIssueAdoption(state, options) {
|
|
27380
|
+
if (!Object.prototype.hasOwnProperty.call(state, ISSUE_ADOPTION_KEY)) {
|
|
27381
|
+
return { errors: [], waivedTools: /* @__PURE__ */ new Set() };
|
|
27382
|
+
}
|
|
27383
|
+
const adoption = state[ISSUE_ADOPTION_KEY];
|
|
27384
|
+
if (!isPlainObject3(adoption)) {
|
|
27385
|
+
return { errors: [ERROR_NOT_OBJECT], waivedTools: /* @__PURE__ */ new Set() };
|
|
27386
|
+
}
|
|
27387
|
+
const errors = [
|
|
27388
|
+
...issueIdentityErrors(adoption, state),
|
|
27389
|
+
...provenanceErrors(adoption)
|
|
27390
|
+
];
|
|
27391
|
+
const waived = waivedToolList(adoption["waived_tools"]);
|
|
27392
|
+
if (waived === null) {
|
|
27393
|
+
errors.push(ERROR_WAIVED_TOOLS_SHAPE);
|
|
27394
|
+
return { errors, waivedTools: /* @__PURE__ */ new Set() };
|
|
27395
|
+
}
|
|
27396
|
+
errors.push(...waivedToolErrors(waived, options));
|
|
27397
|
+
errors.push(...potentialRecordErrors(waived, adoption["potential_record"]));
|
|
27398
|
+
if (errors.length > 0) {
|
|
27399
|
+
return { errors, waivedTools: /* @__PURE__ */ new Set() };
|
|
27400
|
+
}
|
|
27401
|
+
return { errors: [], waivedTools: new Set(waived) };
|
|
27402
|
+
}
|
|
27403
|
+
|
|
27197
27404
|
// ../../extensions/drm-copilot/src/lib/validate/orchestrator-state-routing.ts
|
|
27198
27405
|
var ROUTING_MATRIX_RELATIVE_PATH = "config/orchestration-routing.json";
|
|
27199
27406
|
var MANDATORY_ROUTE_PHASES = {
|
|
@@ -27382,7 +27589,10 @@ function validateRoutingContract(state, options = {}) {
|
|
|
27382
27589
|
const errors = [];
|
|
27383
27590
|
const requiredAgents = routeList(rawRoute, "required_agents");
|
|
27384
27591
|
const requiredSkills = routeList(rawRoute, "required_skills");
|
|
27385
|
-
const requiredMcpTools =
|
|
27592
|
+
const requiredMcpTools = resolvePromotionEntryTools(
|
|
27593
|
+
routeList(rawRoute, "required_mcp_tools"),
|
|
27594
|
+
state
|
|
27595
|
+
);
|
|
27386
27596
|
if (stateList(state, "required_agents", requiredAgents) === null) {
|
|
27387
27597
|
errors.push(
|
|
27388
27598
|
`Checkpoint required_agents must match routing matrix for route ${routeId}.`
|
|
@@ -27411,11 +27621,20 @@ function validateRoutingContract(state, options = {}) {
|
|
|
27411
27621
|
}
|
|
27412
27622
|
}
|
|
27413
27623
|
const actualTools = mcpTools(state);
|
|
27624
|
+
const adoption = resolveIssueAdoption(state, {
|
|
27625
|
+
routeId,
|
|
27626
|
+
requiredMcpTools,
|
|
27627
|
+
successfulTools: actualTools
|
|
27628
|
+
});
|
|
27414
27629
|
for (const tool of requiredMcpTools) {
|
|
27630
|
+
if (adoption.waivedTools.has(tool)) {
|
|
27631
|
+
continue;
|
|
27632
|
+
}
|
|
27415
27633
|
if (!actualTools.has(tool)) {
|
|
27416
27634
|
errors.push(`Checkpoint missing successful MCP receipt: ${tool}.`);
|
|
27417
27635
|
}
|
|
27418
27636
|
}
|
|
27637
|
+
errors.push(...adoption.errors);
|
|
27419
27638
|
errors.push(...validateEmptyListField(state, "local_execution_overrides"));
|
|
27420
27639
|
errors.push(...validateEmptyListField(state, "delegation_bypasses"));
|
|
27421
27640
|
errors.push(...validateLifecycleOperations(state));
|
|
@@ -27561,14 +27780,137 @@ function validateHumanInteraction(humanInteraction) {
|
|
|
27561
27780
|
return errors;
|
|
27562
27781
|
}
|
|
27563
27782
|
|
|
27783
|
+
// ../../extensions/drm-copilot/src/lib/validate/orchestrator-state-remediation-accounting.ts
|
|
27784
|
+
var REVIEW_OUTCOMES_KEY = "review_outcomes";
|
|
27785
|
+
var REVIEW_VERDICTS = [
|
|
27786
|
+
"PASS",
|
|
27787
|
+
"REMEDIATION_REQUIRED",
|
|
27788
|
+
"HALT_NON_REMEDIABLE",
|
|
27789
|
+
"AWAITING_CI"
|
|
27790
|
+
];
|
|
27791
|
+
var REMEDIABILITY_CLASSES = [
|
|
27792
|
+
"autonomous",
|
|
27793
|
+
"external_dependency",
|
|
27794
|
+
"policy_hold",
|
|
27795
|
+
"awaiting_ci",
|
|
27796
|
+
"human_decision_required"
|
|
27797
|
+
];
|
|
27798
|
+
var HALT_CLASSES = /* @__PURE__ */ new Set([
|
|
27799
|
+
"external_dependency",
|
|
27800
|
+
"policy_hold",
|
|
27801
|
+
"human_decision_required"
|
|
27802
|
+
]);
|
|
27803
|
+
var REMEDIABLE_CLASS = "autonomous";
|
|
27804
|
+
function isObject11(value) {
|
|
27805
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27806
|
+
}
|
|
27807
|
+
function pythonRepr8(value) {
|
|
27808
|
+
if (value === null || value === void 0) {
|
|
27809
|
+
return "None";
|
|
27810
|
+
}
|
|
27811
|
+
if (value === true) {
|
|
27812
|
+
return "True";
|
|
27813
|
+
}
|
|
27814
|
+
if (value === false) {
|
|
27815
|
+
return "False";
|
|
27816
|
+
}
|
|
27817
|
+
return String(value);
|
|
27818
|
+
}
|
|
27819
|
+
function deriveReviewVerdict(remediabilities) {
|
|
27820
|
+
for (const value of remediabilities) {
|
|
27821
|
+
if (!REMEDIABILITY_CLASSES.includes(value)) {
|
|
27822
|
+
throw new RangeError(`invalid remediability: ${value}`);
|
|
27823
|
+
}
|
|
27824
|
+
}
|
|
27825
|
+
if (remediabilities.length === 0) {
|
|
27826
|
+
return "PASS";
|
|
27827
|
+
}
|
|
27828
|
+
if (remediabilities.includes(REMEDIABLE_CLASS)) {
|
|
27829
|
+
return "REMEDIATION_REQUIRED";
|
|
27830
|
+
}
|
|
27831
|
+
if (remediabilities.some((value) => HALT_CLASSES.has(value))) {
|
|
27832
|
+
return "HALT_NON_REMEDIABLE";
|
|
27833
|
+
}
|
|
27834
|
+
return "AWAITING_CI";
|
|
27835
|
+
}
|
|
27836
|
+
function validateReviewOutcome(index, outcome) {
|
|
27837
|
+
const errors = [];
|
|
27838
|
+
const prefix = `Checkpoint remediation review outcome #${index}`;
|
|
27839
|
+
const verdict = outcome["verdict"];
|
|
27840
|
+
if (typeof verdict !== "string" || !REVIEW_VERDICTS.includes(verdict)) {
|
|
27841
|
+
errors.push(
|
|
27842
|
+
`${prefix} verdict must be one of PASS, REMEDIATION_REQUIRED, HALT_NON_REMEDIABLE, AWAITING_CI; got: ${pythonRepr8(verdict)}`
|
|
27843
|
+
);
|
|
27844
|
+
}
|
|
27845
|
+
const classes = [];
|
|
27846
|
+
const findings = outcome["findings"];
|
|
27847
|
+
if (!Array.isArray(findings)) {
|
|
27848
|
+
errors.push(`${prefix} findings must be a list.`);
|
|
27849
|
+
} else {
|
|
27850
|
+
findings.forEach((finding, findingIndex) => {
|
|
27851
|
+
if (!isObject11(finding)) {
|
|
27852
|
+
errors.push(`${prefix} finding #${findingIndex} must be an object.`);
|
|
27853
|
+
return;
|
|
27854
|
+
}
|
|
27855
|
+
const remediability = finding["remediability"];
|
|
27856
|
+
if (typeof remediability !== "string" || !REMEDIABILITY_CLASSES.includes(remediability)) {
|
|
27857
|
+
errors.push(
|
|
27858
|
+
`${prefix} finding #${findingIndex} remediability must be one of autonomous, external_dependency, policy_hold, awaiting_ci, human_decision_required; got: ${pythonRepr8(remediability)}`
|
|
27859
|
+
);
|
|
27860
|
+
return;
|
|
27861
|
+
}
|
|
27862
|
+
classes.push(remediability);
|
|
27863
|
+
});
|
|
27864
|
+
}
|
|
27865
|
+
if (errors.length === 0) {
|
|
27866
|
+
const expected = deriveReviewVerdict(classes);
|
|
27867
|
+
if (verdict !== expected) {
|
|
27868
|
+
errors.push(
|
|
27869
|
+
`${prefix} verdict ${pythonRepr8(verdict)} does not match its findings (expected ${expected}).`
|
|
27870
|
+
);
|
|
27871
|
+
}
|
|
27872
|
+
}
|
|
27873
|
+
return errors;
|
|
27874
|
+
}
|
|
27875
|
+
function validateReviewOutcomes(loop) {
|
|
27876
|
+
if (!Object.prototype.hasOwnProperty.call(loop, REVIEW_OUTCOMES_KEY)) {
|
|
27877
|
+
return [];
|
|
27878
|
+
}
|
|
27879
|
+
const outcomes = loop[REVIEW_OUTCOMES_KEY];
|
|
27880
|
+
if (!Array.isArray(outcomes)) {
|
|
27881
|
+
return ["Checkpoint remediation_loop review_outcomes must be a list."];
|
|
27882
|
+
}
|
|
27883
|
+
const errors = [];
|
|
27884
|
+
outcomes.forEach((outcome, index) => {
|
|
27885
|
+
if (!isObject11(outcome)) {
|
|
27886
|
+
errors.push(
|
|
27887
|
+
`Checkpoint remediation review outcome #${index} must be an object.`
|
|
27888
|
+
);
|
|
27889
|
+
return;
|
|
27890
|
+
}
|
|
27891
|
+
errors.push(...validateReviewOutcome(index, outcome));
|
|
27892
|
+
});
|
|
27893
|
+
return errors;
|
|
27894
|
+
}
|
|
27895
|
+
|
|
27564
27896
|
// ../../extensions/drm-copilot/src/lib/validate/orchestrator-state-remediation.ts
|
|
27565
27897
|
var REMEDIATION_LOOP_KEY = "remediation_loop";
|
|
27566
27898
|
var REMEDIATION_CYCLES_KEY = "cycles";
|
|
27567
27899
|
var EXECUTION_STATUSES_REQUIRING_CLEAR_PREFLIGHT = /* @__PURE__ */ new Set(["in_progress", "complete", "failed"]);
|
|
27568
27900
|
var PREFLIGHT_CLEARED_STATUS = "clear";
|
|
27569
|
-
|
|
27901
|
+
var COMPLETED_ATTEMPTS_KEY = "completed_attempts";
|
|
27902
|
+
var CANDIDATE_APPLIED_KEY = "candidate_applied";
|
|
27903
|
+
var OPENED_BY_REVIEW_KEY = "opened_by_review";
|
|
27904
|
+
var COMPLETED_EXECUTION_STATUS = "complete";
|
|
27905
|
+
function isObject12(value) {
|
|
27570
27906
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27571
27907
|
}
|
|
27908
|
+
function isStrictInteger(value) {
|
|
27909
|
+
return typeof value === "number" && Number.isInteger(value);
|
|
27910
|
+
}
|
|
27911
|
+
function hasKey(value, key) {
|
|
27912
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
27913
|
+
}
|
|
27572
27914
|
function validateRemediationCycle(index, cycle) {
|
|
27573
27915
|
const errors = [];
|
|
27574
27916
|
const planPath = cycle["plan_path"];
|
|
@@ -27580,7 +27922,7 @@ function validateRemediationCycle(index, cycle) {
|
|
|
27580
27922
|
const executionStatus = cycle["execution_status"];
|
|
27581
27923
|
if (typeof executionStatus === "string" && EXECUTION_STATUSES_REQUIRING_CLEAR_PREFLIGHT.has(executionStatus)) {
|
|
27582
27924
|
const preflight = cycle["preflight"];
|
|
27583
|
-
const preflightStatus =
|
|
27925
|
+
const preflightStatus = isObject12(preflight) ? preflight["final_status"] : void 0;
|
|
27584
27926
|
if (preflightStatus !== PREFLIGHT_CLEARED_STATUS) {
|
|
27585
27927
|
errors.push(
|
|
27586
27928
|
`Checkpoint remediation cycle #${index} execution_status is ${executionStatus} but preflight.final_status is not 'clear'.`
|
|
@@ -27594,22 +27936,79 @@ function validateRemediationCycle(index, cycle) {
|
|
|
27594
27936
|
}
|
|
27595
27937
|
return errors;
|
|
27596
27938
|
}
|
|
27939
|
+
function opensRemediationReview(openedByReview, outcomes) {
|
|
27940
|
+
if (!isStrictInteger(openedByReview) || !Array.isArray(outcomes)) {
|
|
27941
|
+
return false;
|
|
27942
|
+
}
|
|
27943
|
+
if (openedByReview < 0 || openedByReview >= outcomes.length) {
|
|
27944
|
+
return false;
|
|
27945
|
+
}
|
|
27946
|
+
const target = outcomes[openedByReview];
|
|
27947
|
+
return isObject12(target) && target["verdict"] === "REMEDIATION_REQUIRED";
|
|
27948
|
+
}
|
|
27949
|
+
function validateRemediationAccounting(loop, cycleList) {
|
|
27950
|
+
const errors = [];
|
|
27951
|
+
const outcomes = loop[REVIEW_OUTCOMES_KEY];
|
|
27952
|
+
let appliedCount = 0;
|
|
27953
|
+
(cycleList ?? []).forEach((cycle, index) => {
|
|
27954
|
+
if (!isObject12(cycle)) {
|
|
27955
|
+
return;
|
|
27956
|
+
}
|
|
27957
|
+
const prefix = `Checkpoint remediation cycle #${index}`;
|
|
27958
|
+
if (hasKey(cycle, CANDIDATE_APPLIED_KEY)) {
|
|
27959
|
+
const candidateApplied = cycle[CANDIDATE_APPLIED_KEY];
|
|
27960
|
+
if (typeof candidateApplied !== "boolean") {
|
|
27961
|
+
errors.push(`${prefix} candidate_applied must be a boolean.`);
|
|
27962
|
+
} else if (candidateApplied) {
|
|
27963
|
+
appliedCount += 1;
|
|
27964
|
+
if (cycle["execution_status"] !== COMPLETED_EXECUTION_STATUS) {
|
|
27965
|
+
errors.push(
|
|
27966
|
+
`${prefix} candidate_applied is true but execution_status is not 'complete'.`
|
|
27967
|
+
);
|
|
27968
|
+
}
|
|
27969
|
+
}
|
|
27970
|
+
}
|
|
27971
|
+
if (hasKey(cycle, OPENED_BY_REVIEW_KEY) && !opensRemediationReview(cycle[OPENED_BY_REVIEW_KEY], outcomes)) {
|
|
27972
|
+
errors.push(
|
|
27973
|
+
`${prefix} opened_by_review must reference a review outcome whose verdict is REMEDIATION_REQUIRED.`
|
|
27974
|
+
);
|
|
27975
|
+
}
|
|
27976
|
+
});
|
|
27977
|
+
if (hasKey(loop, COMPLETED_ATTEMPTS_KEY)) {
|
|
27978
|
+
const completedAttempts = loop[COMPLETED_ATTEMPTS_KEY];
|
|
27979
|
+
if (!isStrictInteger(completedAttempts) || completedAttempts < 0) {
|
|
27980
|
+
errors.push(
|
|
27981
|
+
"Checkpoint remediation_loop completed_attempts must be a non-negative integer."
|
|
27982
|
+
);
|
|
27983
|
+
} else if (completedAttempts !== appliedCount) {
|
|
27984
|
+
errors.push(
|
|
27985
|
+
`Checkpoint remediation_loop completed_attempts is ${completedAttempts} but ${appliedCount} cycles have candidate_applied true.`
|
|
27986
|
+
);
|
|
27987
|
+
}
|
|
27988
|
+
}
|
|
27989
|
+
return errors;
|
|
27990
|
+
}
|
|
27597
27991
|
function validateRemediationLoop(remediationLoop) {
|
|
27598
27992
|
const errors = [];
|
|
27599
|
-
if (!
|
|
27993
|
+
if (!isObject12(remediationLoop)) {
|
|
27600
27994
|
return errors;
|
|
27601
27995
|
}
|
|
27602
27996
|
const cycles = remediationLoop[REMEDIATION_CYCLES_KEY];
|
|
27603
|
-
|
|
27604
|
-
|
|
27997
|
+
let cycleList = null;
|
|
27998
|
+
if (Array.isArray(cycles)) {
|
|
27999
|
+
cycleList = cycles;
|
|
28000
|
+
cycles.forEach((cycle, index) => {
|
|
28001
|
+
if (!isObject12(cycle)) {
|
|
28002
|
+
errors.push(
|
|
28003
|
+
`Checkpoint remediation cycle #${index} must be an object.`
|
|
28004
|
+
);
|
|
28005
|
+
return;
|
|
28006
|
+
}
|
|
28007
|
+
errors.push(...validateRemediationCycle(index, cycle));
|
|
28008
|
+
});
|
|
27605
28009
|
}
|
|
27606
|
-
|
|
27607
|
-
|
|
27608
|
-
errors.push(`Checkpoint remediation cycle #${index} must be an object.`);
|
|
27609
|
-
return;
|
|
27610
|
-
}
|
|
27611
|
-
errors.push(...validateRemediationCycle(index, cycle));
|
|
27612
|
-
});
|
|
28010
|
+
errors.push(...validateReviewOutcomes(remediationLoop));
|
|
28011
|
+
errors.push(...validateRemediationAccounting(remediationLoop, cycleList));
|
|
27613
28012
|
return errors;
|
|
27614
28013
|
}
|
|
27615
28014
|
|
|
@@ -27623,7 +28022,7 @@ var OUT_OF_SCOPE_STEP_KEYS = [
|
|
|
27623
28022
|
"step9_status",
|
|
27624
28023
|
"step10_status"
|
|
27625
28024
|
];
|
|
27626
|
-
function
|
|
28025
|
+
function pythonRepr9(value) {
|
|
27627
28026
|
if (value === void 0 || value === null) {
|
|
27628
28027
|
return "None";
|
|
27629
28028
|
}
|
|
@@ -27638,11 +28037,11 @@ function pythonRepr8(value) {
|
|
|
27638
28037
|
return String(value);
|
|
27639
28038
|
}
|
|
27640
28039
|
if (Array.isArray(value)) {
|
|
27641
|
-
return `[${value.map(
|
|
28040
|
+
return `[${value.map(pythonRepr9).join(", ")}]`;
|
|
27642
28041
|
}
|
|
27643
28042
|
if (typeof value === "object") {
|
|
27644
28043
|
const entries = Object.entries(value).map(
|
|
27645
|
-
([key, item]) => `${
|
|
28044
|
+
([key, item]) => `${pythonRepr9(key)}: ${pythonRepr9(item)}`
|
|
27646
28045
|
);
|
|
27647
28046
|
return `{${entries.join(", ")}}`;
|
|
27648
28047
|
}
|
|
@@ -27656,13 +28055,13 @@ function validatePreparationTerminalContract(state) {
|
|
|
27656
28055
|
const errors = [];
|
|
27657
28056
|
if (state["next_step"] !== EXPECTED_NEXT_STEP) {
|
|
27658
28057
|
errors.push(
|
|
27659
|
-
`Preparation checkpoint next_step must be ${
|
|
28058
|
+
`Preparation checkpoint next_step must be ${pythonRepr9(EXPECTED_NEXT_STEP)}, found ${pythonRepr9(state["next_step"])}.`
|
|
27660
28059
|
);
|
|
27661
28060
|
}
|
|
27662
28061
|
for (const key of OUT_OF_SCOPE_STEP_KEYS) {
|
|
27663
28062
|
if (state[key] !== "not-applicable") {
|
|
27664
28063
|
errors.push(
|
|
27665
|
-
`Preparation checkpoint ${key} must be 'not-applicable', found ${
|
|
28064
|
+
`Preparation checkpoint ${key} must be 'not-applicable', found ${pythonRepr9(state[key])}.`
|
|
27666
28065
|
);
|
|
27667
28066
|
}
|
|
27668
28067
|
}
|
|
@@ -27678,18 +28077,18 @@ var DELEGATING_AGENTS = /* @__PURE__ */ new Set([
|
|
|
27678
28077
|
"prd-feature",
|
|
27679
28078
|
"pr-author"
|
|
27680
28079
|
]);
|
|
27681
|
-
function
|
|
28080
|
+
function isObject13(value) {
|
|
27682
28081
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27683
28082
|
}
|
|
27684
28083
|
function delegatedAgents(state) {
|
|
27685
28084
|
const agents = /* @__PURE__ */ new Set();
|
|
27686
28085
|
let receipts = state["delegation_receipts"];
|
|
27687
|
-
if (
|
|
28086
|
+
if (isObject13(receipts)) {
|
|
27688
28087
|
receipts = receipts["agents"];
|
|
27689
28088
|
}
|
|
27690
28089
|
if (Array.isArray(receipts)) {
|
|
27691
28090
|
for (const receipt of receipts) {
|
|
27692
|
-
if (!
|
|
28091
|
+
if (!isObject13(receipt)) {
|
|
27693
28092
|
continue;
|
|
27694
28093
|
}
|
|
27695
28094
|
const agentName = receipt["agent_name"];
|
|
@@ -27713,7 +28112,7 @@ function validateModelRoutingExistence(state) {
|
|
|
27713
28112
|
const receipts = state["model_routing_receipts"];
|
|
27714
28113
|
if (Array.isArray(receipts)) {
|
|
27715
28114
|
for (const receipt of receipts) {
|
|
27716
|
-
if (!
|
|
28115
|
+
if (!isObject13(receipt)) {
|
|
27717
28116
|
continue;
|
|
27718
28117
|
}
|
|
27719
28118
|
const agent = receipt["agent"];
|
|
@@ -27762,15 +28161,6 @@ var VALID_STEP_STATUS = /* @__PURE__ */ new Set([
|
|
|
27762
28161
|
"in_progress",
|
|
27763
28162
|
"completed"
|
|
27764
28163
|
]);
|
|
27765
|
-
var VALID_BLOCKED_REASONS = /* @__PURE__ */ new Set([
|
|
27766
|
-
"none",
|
|
27767
|
-
"spawn_agent_unavailable",
|
|
27768
|
-
"delegation_launch_failed",
|
|
27769
|
-
"delegate_no_receipt",
|
|
27770
|
-
"delegate_contract_incomplete",
|
|
27771
|
-
"validator_failed",
|
|
27772
|
-
"user_requested_stop"
|
|
27773
|
-
]);
|
|
27774
28164
|
var REQUIRED_RECEIPT_KEYS = [
|
|
27775
28165
|
"step",
|
|
27776
28166
|
"agent_name",
|
|
@@ -27810,13 +28200,13 @@ function isValidStepStatus(key, value) {
|
|
|
27810
28200
|
}
|
|
27811
28201
|
return STEP_SPECIFIC_EXTRA_STATUS.get(key)?.has(value) === true;
|
|
27812
28202
|
}
|
|
27813
|
-
function
|
|
28203
|
+
function isObject14(value) {
|
|
27814
28204
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27815
28205
|
}
|
|
27816
28206
|
function validateListDelegationReceipts(receipts) {
|
|
27817
28207
|
const errors = [];
|
|
27818
28208
|
receipts.forEach((receipt, index) => {
|
|
27819
|
-
if (!
|
|
28209
|
+
if (!isObject14(receipt)) {
|
|
27820
28210
|
errors.push(`Checkpoint delegation receipt #${index} must be an object.`);
|
|
27821
28211
|
return;
|
|
27822
28212
|
}
|
|
@@ -27858,7 +28248,7 @@ function validateNamespacedDelegationReceipts(receipts) {
|
|
|
27858
28248
|
if (promotionReceipts === void 0 || promotionReceipts === null) {
|
|
27859
28249
|
return errors;
|
|
27860
28250
|
}
|
|
27861
|
-
if (!
|
|
28251
|
+
if (!isObject14(promotionReceipts)) {
|
|
27862
28252
|
errors.push(
|
|
27863
28253
|
"Checkpoint delegation_receipts.promotion must be an object namespace."
|
|
27864
28254
|
);
|
|
@@ -27893,7 +28283,7 @@ function validateOrchestratorStateText(text2, options = {}) {
|
|
|
27893
28283
|
`Checkpoint is not valid JSON: ${exc instanceof Error ? exc.message : String(exc)}`
|
|
27894
28284
|
];
|
|
27895
28285
|
}
|
|
27896
|
-
if (!
|
|
28286
|
+
if (!isObject14(state)) {
|
|
27897
28287
|
return ["Checkpoint root must be a JSON object."];
|
|
27898
28288
|
}
|
|
27899
28289
|
const stateMap = state;
|
|
@@ -27918,7 +28308,7 @@ function validateOrchestratorStateText(text2, options = {}) {
|
|
|
27918
28308
|
if (receipts !== void 0 && receipts !== null) {
|
|
27919
28309
|
if (Array.isArray(receipts)) {
|
|
27920
28310
|
errors.push(...validateListDelegationReceipts(receipts));
|
|
27921
|
-
} else if (
|
|
28311
|
+
} else if (isObject14(receipts)) {
|
|
27922
28312
|
errors.push(...validateNamespacedDelegationReceipts(receipts));
|
|
27923
28313
|
} else {
|
|
27924
28314
|
errors.push(
|
|
@@ -28955,10 +29345,10 @@ var PROHIBITED_ANY_LEVEL_KEYS = words(
|
|
|
28955
29345
|
"depends_on integration_branch epic_merge_pr"
|
|
28956
29346
|
);
|
|
28957
29347
|
var ROOT_PATH = "<root>";
|
|
28958
|
-
function
|
|
29348
|
+
function isObject15(value) {
|
|
28959
29349
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28960
29350
|
}
|
|
28961
|
-
function
|
|
29351
|
+
function pythonRepr10(value) {
|
|
28962
29352
|
if (value === null || value === void 0) {
|
|
28963
29353
|
return "None";
|
|
28964
29354
|
}
|
|
@@ -28969,18 +29359,18 @@ function pythonRepr9(value) {
|
|
|
28969
29359
|
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
28970
29360
|
}
|
|
28971
29361
|
if (Array.isArray(value)) {
|
|
28972
|
-
return `[${value.map(
|
|
29362
|
+
return `[${value.map(pythonRepr10).join(", ")}]`;
|
|
28973
29363
|
}
|
|
28974
|
-
if (
|
|
29364
|
+
if (isObject15(value)) {
|
|
28975
29365
|
const pairs = Object.entries(value).map(
|
|
28976
|
-
([key, item]) => `${
|
|
29366
|
+
([key, item]) => `${pythonRepr10(key)}: ${pythonRepr10(item)}`
|
|
28977
29367
|
);
|
|
28978
29368
|
return `{${pairs.join(", ")}}`;
|
|
28979
29369
|
}
|
|
28980
29370
|
return String(value);
|
|
28981
29371
|
}
|
|
28982
29372
|
function pythonStr2(value) {
|
|
28983
|
-
return typeof value === "string" ? value :
|
|
29373
|
+
return typeof value === "string" ? value : pythonRepr10(value);
|
|
28984
29374
|
}
|
|
28985
29375
|
function isEnumMember(members, value) {
|
|
28986
29376
|
return typeof value === "string" && members.includes(value);
|
|
@@ -29004,13 +29394,13 @@ function inBoundedRange(value, minimum, maximum) {
|
|
|
29004
29394
|
return isIntegral(value) && value >= minimum && value <= maximum;
|
|
29005
29395
|
}
|
|
29006
29396
|
function enumError(context, field, members, value) {
|
|
29007
|
-
return `${context} ${field} must be one of ${members.join(", ")}; found: ${
|
|
29397
|
+
return `${context} ${field} must be one of ${members.join(", ")}; found: ${pythonRepr10(value)}.`;
|
|
29008
29398
|
}
|
|
29009
29399
|
function itemContext(context, index) {
|
|
29010
29400
|
return `${context} items[${index}]`;
|
|
29011
29401
|
}
|
|
29012
29402
|
function validateBlastRadiusBlock(radius, context) {
|
|
29013
|
-
if (!
|
|
29403
|
+
if (!isObject15(radius)) {
|
|
29014
29404
|
return [`${context} blast_radius must be an object.`];
|
|
29015
29405
|
}
|
|
29016
29406
|
const errors = [];
|
|
@@ -29046,25 +29436,25 @@ function validateMergeStatus(record3, context, state) {
|
|
|
29046
29436
|
}
|
|
29047
29437
|
if (isEnumMember(MERGED_MERGE_STATUSES, mergeStatus) && state !== "merged") {
|
|
29048
29438
|
return [
|
|
29049
|
-
`${context} merge_status ${
|
|
29439
|
+
`${context} merge_status ${pythonRepr10(mergeStatus)} requires state 'merged'; found: ${pythonRepr10(state)}.`
|
|
29050
29440
|
];
|
|
29051
29441
|
}
|
|
29052
29442
|
if (isEnumMember(BLOCKED_MERGE_STATUSES, mergeStatus) && state !== "blocked") {
|
|
29053
29443
|
return [
|
|
29054
|
-
`${context} merge_status ${
|
|
29444
|
+
`${context} merge_status ${pythonRepr10(mergeStatus)} requires state 'blocked'; found: ${pythonRepr10(state)}.`
|
|
29055
29445
|
];
|
|
29056
29446
|
}
|
|
29057
29447
|
return [];
|
|
29058
29448
|
}
|
|
29059
29449
|
function validateItemRecord(item, context, requireKind = false) {
|
|
29060
|
-
if (!
|
|
29450
|
+
if (!isObject15(item)) {
|
|
29061
29451
|
return [`${context} must be an object.`];
|
|
29062
29452
|
}
|
|
29063
29453
|
const errors = [];
|
|
29064
29454
|
const issueNum = item["issue_num"];
|
|
29065
29455
|
if (!isPositiveInteger(issueNum)) {
|
|
29066
29456
|
errors.push(
|
|
29067
|
-
`${context} issue_num must be a positive integer; found: ${
|
|
29457
|
+
`${context} issue_num must be a positive integer; found: ${pythonRepr10(issueNum)}.`
|
|
29068
29458
|
);
|
|
29069
29459
|
}
|
|
29070
29460
|
if (!isNonEmptyString2(item["feature_folder"])) {
|
|
@@ -29095,7 +29485,7 @@ function validateItems(items, context, requireKind = false) {
|
|
|
29095
29485
|
errors.push(
|
|
29096
29486
|
...validateItemRecord(entry, itemContext(context, index), requireKind)
|
|
29097
29487
|
);
|
|
29098
|
-
if (!
|
|
29488
|
+
if (!isObject15(entry)) {
|
|
29099
29489
|
return;
|
|
29100
29490
|
}
|
|
29101
29491
|
const issueNum = entry["issue_num"];
|
|
@@ -29114,7 +29504,7 @@ function validateItems(items, context, requireKind = false) {
|
|
|
29114
29504
|
}
|
|
29115
29505
|
function prohibitedKeyErrors(value, path16, context, keys) {
|
|
29116
29506
|
const errors = [];
|
|
29117
|
-
if (
|
|
29507
|
+
if (isObject15(value)) {
|
|
29118
29508
|
for (const [key, child] of Object.entries(value)) {
|
|
29119
29509
|
if (keys.includes(key)) {
|
|
29120
29510
|
errors.push(`${context} carries prohibited key '${key}' at ${path16}.`);
|
|
@@ -29133,7 +29523,7 @@ function prohibitedKeyErrors(value, path16, context, keys) {
|
|
|
29133
29523
|
}
|
|
29134
29524
|
function scanProhibitedKeys(root, context, deepKeys = PROHIBITED_ANY_LEVEL_KEYS, topLevelKeys = []) {
|
|
29135
29525
|
const errors = prohibitedKeyErrors(root, ROOT_PATH, context, deepKeys);
|
|
29136
|
-
if (
|
|
29526
|
+
if (isObject15(root) && topLevelKeys.length > 0) {
|
|
29137
29527
|
for (const key of topLevelKeys) {
|
|
29138
29528
|
if (key in root) {
|
|
29139
29529
|
errors.push(
|
|
@@ -29149,7 +29539,7 @@ function scanProhibitedKeys(root, context, deepKeys = PROHIBITED_ANY_LEVEL_KEYS,
|
|
|
29149
29539
|
var VIOLATION_PREFIX = "PARALLEL_COHORT_BARRIER_VIOLATION";
|
|
29150
29540
|
var ITEM_START_TIMESTAMP_FIELD = "worktree_created_at";
|
|
29151
29541
|
var MERGE_CONFIRMATION_TIMESTAMP_FIELD = "merged_at";
|
|
29152
|
-
var
|
|
29542
|
+
var NOT_STARTED_MERGE_STATUS2 = "not_started";
|
|
29153
29543
|
var GATING_KEYS = ["conflict_edges", "cohorts"];
|
|
29154
29544
|
var FOLDER_HINT_PREFIXES = [
|
|
29155
29545
|
"docs/features/active/",
|
|
@@ -29172,7 +29562,7 @@ function buildReferenceIndex(items) {
|
|
|
29172
29562
|
return { records, byFolderHint };
|
|
29173
29563
|
}
|
|
29174
29564
|
for (const entry of items) {
|
|
29175
|
-
if (!
|
|
29565
|
+
if (!isObject15(entry)) {
|
|
29176
29566
|
continue;
|
|
29177
29567
|
}
|
|
29178
29568
|
const issueNum = entry["issue_num"];
|
|
@@ -29207,7 +29597,7 @@ function cohortIndexByItem(cohorts, recolorGeneration, references) {
|
|
|
29207
29597
|
return assignments;
|
|
29208
29598
|
}
|
|
29209
29599
|
for (const entry of cohorts) {
|
|
29210
|
-
if (!
|
|
29600
|
+
if (!isObject15(entry) || entry["generation"] !== recolorGeneration) {
|
|
29211
29601
|
continue;
|
|
29212
29602
|
}
|
|
29213
29603
|
const cohortIndex = entry["index"];
|
|
@@ -29224,13 +29614,13 @@ function cohortIndexByItem(cohorts, recolorGeneration, references) {
|
|
|
29224
29614
|
}
|
|
29225
29615
|
return assignments;
|
|
29226
29616
|
}
|
|
29227
|
-
function
|
|
29617
|
+
function hasStarted2(record3) {
|
|
29228
29618
|
const start = record3[ITEM_START_TIMESTAMP_FIELD];
|
|
29229
29619
|
if (typeof start === "string" && start.trim().length > 0) {
|
|
29230
29620
|
return true;
|
|
29231
29621
|
}
|
|
29232
29622
|
const mergeStatus = record3["merge_status"];
|
|
29233
|
-
return typeof mergeStatus === "string" && mergeStatus !==
|
|
29623
|
+
return typeof mergeStatus === "string" && mergeStatus !== NOT_STARTED_MERGE_STATUS2;
|
|
29234
29624
|
}
|
|
29235
29625
|
function satisfiesBarrier(record3) {
|
|
29236
29626
|
return isEnumMember(MERGED_MERGE_STATUSES, record3["merge_status"]);
|
|
@@ -29258,7 +29648,7 @@ function violationEndpoints(first, second, assignments, records) {
|
|
|
29258
29648
|
if (earlier === void 0 || later === void 0) {
|
|
29259
29649
|
return null;
|
|
29260
29650
|
}
|
|
29261
|
-
const statusViolation =
|
|
29651
|
+
const statusViolation = hasStarted2(later) && !satisfiesBarrier(earlier);
|
|
29262
29652
|
if (statusViolation || mergeConfirmedAfterStart(earlier, later)) {
|
|
29263
29653
|
return [earlierKey, laterKey];
|
|
29264
29654
|
}
|
|
@@ -29280,7 +29670,7 @@ function validateCohortBarrierOrdering(state) {
|
|
|
29280
29670
|
);
|
|
29281
29671
|
const errors = [];
|
|
29282
29672
|
for (const entry of edges) {
|
|
29283
|
-
if (!
|
|
29673
|
+
if (!isObject15(entry)) {
|
|
29284
29674
|
continue;
|
|
29285
29675
|
}
|
|
29286
29676
|
const first = resolveReference(entry["a"], references);
|
|
@@ -29318,14 +29708,14 @@ function validateMutationItemKey(entry, entryContext, op, issueNums) {
|
|
|
29318
29708
|
if (op === "close") {
|
|
29319
29709
|
if (!isNone(itemKey)) {
|
|
29320
29710
|
return [
|
|
29321
|
-
`${entryContext} item_key must be null for op 'close'; found: ${
|
|
29711
|
+
`${entryContext} item_key must be null for op 'close'; found: ${pythonRepr10(itemKey)}.`
|
|
29322
29712
|
];
|
|
29323
29713
|
}
|
|
29324
29714
|
return [];
|
|
29325
29715
|
}
|
|
29326
29716
|
if (isEnumMember(OPS_REQUIRING_ITEM_KEY, op) && !resolves(itemKey, issueNums)) {
|
|
29327
29717
|
return [
|
|
29328
|
-
`${entryContext} item_key ${
|
|
29718
|
+
`${entryContext} item_key ${pythonRepr10(itemKey)} does not resolve to an items[].issue_num.`
|
|
29329
29719
|
];
|
|
29330
29720
|
}
|
|
29331
29721
|
return [];
|
|
@@ -29337,12 +29727,12 @@ function validateMutationStateField(entry, entryContext, field, op, nullOps) {
|
|
|
29337
29727
|
}
|
|
29338
29728
|
if (isEnumMember(nullOps, op)) {
|
|
29339
29729
|
return [
|
|
29340
|
-
`${entryContext} ${field} must be null for op ${
|
|
29730
|
+
`${entryContext} ${field} must be null for op ${pythonRepr10(op)}; found: ${pythonRepr10(value)}.`
|
|
29341
29731
|
];
|
|
29342
29732
|
}
|
|
29343
29733
|
if (!isEnumMember(VALID_ITEM_STATES, value)) {
|
|
29344
29734
|
return [
|
|
29345
|
-
`${entryContext} ${field} must be null or one of ${VALID_ITEM_STATES.join(", ")}; found: ${
|
|
29735
|
+
`${entryContext} ${field} must be null or one of ${VALID_ITEM_STATES.join(", ")}; found: ${pythonRepr10(value)}.`
|
|
29346
29736
|
];
|
|
29347
29737
|
}
|
|
29348
29738
|
return [];
|
|
@@ -29352,14 +29742,14 @@ function validateMutationDisposition(entry, entryContext, op) {
|
|
|
29352
29742
|
if (op === "remove" && entry["prior_state"] === "in_flight") {
|
|
29353
29743
|
if (!isEnumMember(VALID_DISPOSITIONS, disposition)) {
|
|
29354
29744
|
return [
|
|
29355
|
-
`${entryContext} disposition must be one of ${VALID_DISPOSITIONS.join(", ")} for an in-flight removal; found: ${
|
|
29745
|
+
`${entryContext} disposition must be one of ${VALID_DISPOSITIONS.join(", ")} for an in-flight removal; found: ${pythonRepr10(disposition)}.`
|
|
29356
29746
|
];
|
|
29357
29747
|
}
|
|
29358
29748
|
return [];
|
|
29359
29749
|
}
|
|
29360
29750
|
if (!isNone(disposition)) {
|
|
29361
29751
|
return [
|
|
29362
|
-
`${entryContext} disposition must be null unless op is 'remove' with prior_state 'in_flight'; found: ${
|
|
29752
|
+
`${entryContext} disposition must be null unless op is 'remove' with prior_state 'in_flight'; found: ${pythonRepr10(disposition)}.`
|
|
29363
29753
|
];
|
|
29364
29754
|
}
|
|
29365
29755
|
return [];
|
|
@@ -29368,7 +29758,7 @@ function validateMutationGeneration(entry, entryContext, recolorGeneration) {
|
|
|
29368
29758
|
const generation = entry["recolor_generation"];
|
|
29369
29759
|
if (!isNonNegativeInteger(generation)) {
|
|
29370
29760
|
return [
|
|
29371
|
-
`${entryContext} recolor_generation must be a non-negative integer; found: ${
|
|
29761
|
+
`${entryContext} recolor_generation must be a non-negative integer; found: ${pythonRepr10(generation)}.`
|
|
29372
29762
|
];
|
|
29373
29763
|
}
|
|
29374
29764
|
if (isNonNegativeInteger(recolorGeneration) && typeof generation === "number" && typeof recolorGeneration === "number" && generation > recolorGeneration) {
|
|
@@ -29385,7 +29775,7 @@ function validateMutations(mutations, issueNums, recolorGeneration, context) {
|
|
|
29385
29775
|
const errors = [];
|
|
29386
29776
|
mutations.forEach((entry, position) => {
|
|
29387
29777
|
const entryContext = `${context} mutations[${position}]`;
|
|
29388
|
-
if (!
|
|
29778
|
+
if (!isObject15(entry)) {
|
|
29389
29779
|
errors.push(`${entryContext} must be an object.`);
|
|
29390
29780
|
return;
|
|
29391
29781
|
}
|
|
@@ -29429,14 +29819,14 @@ function validateDriftEvents(events, issueNums, context) {
|
|
|
29429
29819
|
const errors = [];
|
|
29430
29820
|
events.forEach((entry, position) => {
|
|
29431
29821
|
const entryContext = `${context} drift_events[${position}]`;
|
|
29432
|
-
if (!
|
|
29822
|
+
if (!isObject15(entry)) {
|
|
29433
29823
|
errors.push(`${entryContext} must be an object.`);
|
|
29434
29824
|
return;
|
|
29435
29825
|
}
|
|
29436
29826
|
const itemKey = entry["item_key"];
|
|
29437
29827
|
if (!resolves(itemKey, issueNums)) {
|
|
29438
29828
|
errors.push(
|
|
29439
|
-
`${entryContext} item_key ${
|
|
29829
|
+
`${entryContext} item_key ${pythonRepr10(itemKey)} does not resolve to an items[].issue_num.`
|
|
29440
29830
|
);
|
|
29441
29831
|
}
|
|
29442
29832
|
for (const field of ["declared", "observed"]) {
|
|
@@ -29474,7 +29864,7 @@ function collectItemKeysAndStates(items) {
|
|
|
29474
29864
|
return pairs;
|
|
29475
29865
|
}
|
|
29476
29866
|
for (const entry of items) {
|
|
29477
|
-
if (!
|
|
29867
|
+
if (!isObject15(entry)) {
|
|
29478
29868
|
continue;
|
|
29479
29869
|
}
|
|
29480
29870
|
const issueNum = entry["issue_num"];
|
|
@@ -29492,13 +29882,13 @@ function validateCohortEntry(entry, entryContext, issueNums, recolorGeneration)
|
|
|
29492
29882
|
const index = entry["index"];
|
|
29493
29883
|
if (!isNonNegativeInteger(index)) {
|
|
29494
29884
|
errors.push(
|
|
29495
|
-
`${entryContext} index must be a non-negative integer; found: ${
|
|
29885
|
+
`${entryContext} index must be a non-negative integer; found: ${pythonRepr10(index)}.`
|
|
29496
29886
|
);
|
|
29497
29887
|
}
|
|
29498
29888
|
const generation = entry["generation"];
|
|
29499
29889
|
if (!isNonNegativeInteger(generation)) {
|
|
29500
29890
|
errors.push(
|
|
29501
|
-
`${entryContext} generation must be a non-negative integer; found: ${
|
|
29891
|
+
`${entryContext} generation must be a non-negative integer; found: ${pythonRepr10(generation)}.`
|
|
29502
29892
|
);
|
|
29503
29893
|
} else if (recolorGeneration !== null && typeof generation === "number" && generation > recolorGeneration) {
|
|
29504
29894
|
errors.push(
|
|
@@ -29513,7 +29903,7 @@ function validateCohortEntry(entry, entryContext, issueNums, recolorGeneration)
|
|
|
29513
29903
|
for (const key of itemKeys) {
|
|
29514
29904
|
if (typeof key !== "number" || !Number.isInteger(key) || !issueNums.has(key)) {
|
|
29515
29905
|
errors.push(
|
|
29516
|
-
`${entryContext} item_keys entry ${
|
|
29906
|
+
`${entryContext} item_keys entry ${pythonRepr10(key)} does not resolve to an items[].issue_num.`
|
|
29517
29907
|
);
|
|
29518
29908
|
}
|
|
29519
29909
|
}
|
|
@@ -29524,7 +29914,7 @@ function validateCohortShapes(cohorts, issueNums, recolorGeneration, context) {
|
|
|
29524
29914
|
const generationOk = isNonNegativeInteger(recolorGeneration);
|
|
29525
29915
|
if (!generationOk) {
|
|
29526
29916
|
errors.push(
|
|
29527
|
-
`${context} recolor_generation must be a non-negative integer; found: ${
|
|
29917
|
+
`${context} recolor_generation must be a non-negative integer; found: ${pythonRepr10(recolorGeneration)}.`
|
|
29528
29918
|
);
|
|
29529
29919
|
}
|
|
29530
29920
|
if (!Array.isArray(cohorts)) {
|
|
@@ -29534,7 +29924,7 @@ function validateCohortShapes(cohorts, issueNums, recolorGeneration, context) {
|
|
|
29534
29924
|
const bound = generationOk && typeof recolorGeneration === "number" ? recolorGeneration : null;
|
|
29535
29925
|
cohorts.forEach((entry, position) => {
|
|
29536
29926
|
const entryContext = `${context} cohorts[${position}]`;
|
|
29537
|
-
if (!
|
|
29927
|
+
if (!isObject15(entry)) {
|
|
29538
29928
|
errors.push(`${entryContext} must be an object.`);
|
|
29539
29929
|
return;
|
|
29540
29930
|
}
|
|
@@ -29546,7 +29936,7 @@ function currentGenerationCohorts(cohorts, recolorGeneration) {
|
|
|
29546
29936
|
if (!isNonNegativeInteger(recolorGeneration) || !Array.isArray(cohorts)) {
|
|
29547
29937
|
return [];
|
|
29548
29938
|
}
|
|
29549
|
-
return cohorts.filter(
|
|
29939
|
+
return cohorts.filter(isObject15).filter((entry) => entry["generation"] === recolorGeneration);
|
|
29550
29940
|
}
|
|
29551
29941
|
function validateCurrentGenerationCohorts(cohorts, items, recolorGeneration, context) {
|
|
29552
29942
|
const current = currentGenerationCohorts(cohorts, recolorGeneration);
|
|
@@ -29591,7 +29981,7 @@ function validateCurrentGenerationCohorts(cohorts, items, recolorGeneration, con
|
|
|
29591
29981
|
continue;
|
|
29592
29982
|
}
|
|
29593
29983
|
errors.push(
|
|
29594
|
-
`${context} item ${issueNum} in state ${
|
|
29984
|
+
`${context} item ${issueNum} in state ${pythonRepr10(state)} must appear in exactly one current-generation cohort; found ${count}.`
|
|
29595
29985
|
);
|
|
29596
29986
|
}
|
|
29597
29987
|
return errors;
|
|
@@ -29599,7 +29989,7 @@ function validateCurrentGenerationCohorts(cohorts, items, recolorGeneration, con
|
|
|
29599
29989
|
function validateCurrentCohortBound(currentCohort, cohorts, recolorGeneration, context) {
|
|
29600
29990
|
if (!isNonNegativeInteger(currentCohort) || typeof currentCohort !== "number") {
|
|
29601
29991
|
return [
|
|
29602
|
-
`${context} current_cohort must be a non-negative integer; found: ${
|
|
29992
|
+
`${context} current_cohort must be a non-negative integer; found: ${pythonRepr10(currentCohort)}.`
|
|
29603
29993
|
];
|
|
29604
29994
|
}
|
|
29605
29995
|
const indices = [];
|
|
@@ -29629,7 +30019,7 @@ function validateEdgeEndpoints(entry, entryContext, issueNums) {
|
|
|
29629
30019
|
endpoints.set(field, value);
|
|
29630
30020
|
} else {
|
|
29631
30021
|
errors.push(
|
|
29632
|
-
`${entryContext} ${field} ${
|
|
30022
|
+
`${entryContext} ${field} ${pythonRepr10(value)} does not resolve to an items[].issue_num.`
|
|
29633
30023
|
);
|
|
29634
30024
|
}
|
|
29635
30025
|
}
|
|
@@ -29659,7 +30049,7 @@ function validateConflictEdges(edges, issueNums, context) {
|
|
|
29659
30049
|
const duplicates = /* @__PURE__ */ new Map();
|
|
29660
30050
|
edges.forEach((entry, position) => {
|
|
29661
30051
|
const entryContext = `${context} conflict_edges[${position}]`;
|
|
29662
|
-
if (!
|
|
30052
|
+
if (!isObject15(entry)) {
|
|
29663
30053
|
errors.push(`${entryContext} must be an object.`);
|
|
29664
30054
|
return;
|
|
29665
30055
|
}
|
|
@@ -29738,7 +30128,7 @@ function validateIdentity(state) {
|
|
|
29738
30128
|
const routeId = state["route_id"];
|
|
29739
30129
|
if ("route_id" in state && routeId !== EXPECTED_ROUTE_ID2) {
|
|
29740
30130
|
errors.push(
|
|
29741
|
-
`${CONTEXT} route_id must be '${EXPECTED_ROUTE_ID2}'; found: ${
|
|
30131
|
+
`${CONTEXT} route_id must be '${EXPECTED_ROUTE_ID2}'; found: ${pythonRepr10(routeId)}.`
|
|
29742
30132
|
);
|
|
29743
30133
|
}
|
|
29744
30134
|
const mode = state["mode"];
|
|
@@ -29748,7 +30138,7 @@ function validateIdentity(state) {
|
|
|
29748
30138
|
const concurrency = state["max_concurrency"];
|
|
29749
30139
|
if ("max_concurrency" in state && !inBoundedRange(concurrency, MIN_CONCURRENCY, MAX_CONCURRENCY)) {
|
|
29750
30140
|
errors.push(
|
|
29751
|
-
`${CONTEXT} max_concurrency must be an integer from ${MIN_CONCURRENCY} through ${MAX_CONCURRENCY}; found: ${
|
|
30141
|
+
`${CONTEXT} max_concurrency must be an integer from ${MIN_CONCURRENCY} through ${MAX_CONCURRENCY}; found: ${pythonRepr10(concurrency)}.`
|
|
29752
30142
|
);
|
|
29753
30143
|
}
|
|
29754
30144
|
return errors;
|
|
@@ -29804,7 +30194,7 @@ function recordsCloseMutation(state) {
|
|
|
29804
30194
|
return false;
|
|
29805
30195
|
}
|
|
29806
30196
|
return mutations.some(
|
|
29807
|
-
(entry) =>
|
|
30197
|
+
(entry) => isObject15(entry) && entry["op"] === "close"
|
|
29808
30198
|
);
|
|
29809
30199
|
}
|
|
29810
30200
|
function validateCompletion2(state) {
|
|
@@ -29812,7 +30202,7 @@ function validateCompletion2(state) {
|
|
|
29812
30202
|
const items = state["items"];
|
|
29813
30203
|
const entries = Array.isArray(items) ? items : [];
|
|
29814
30204
|
entries.forEach((entry, index) => {
|
|
29815
|
-
if (!
|
|
30205
|
+
if (!isObject15(entry)) {
|
|
29816
30206
|
return;
|
|
29817
30207
|
}
|
|
29818
30208
|
if (entry["state"] === "withdrawn") {
|
|
@@ -29821,7 +30211,7 @@ function validateCompletion2(state) {
|
|
|
29821
30211
|
const mergeStatus = entry["merge_status"];
|
|
29822
30212
|
if (!isEnumMember(MERGED_MERGE_STATUSES, mergeStatus)) {
|
|
29823
30213
|
errors.push(
|
|
29824
|
-
`${itemContext(CONTEXT, index)} completion validation failed: merge_status is not merged or worktree_removed; found: ${
|
|
30214
|
+
`${itemContext(CONTEXT, index)} completion validation failed: merge_status is not merged or worktree_removed; found: ${pythonRepr10(mergeStatus)}.`
|
|
29825
30215
|
);
|
|
29826
30216
|
}
|
|
29827
30217
|
});
|
|
@@ -29840,7 +30230,7 @@ function validateParallelOrchestratorStateText(text2, options = {}) {
|
|
|
29840
30230
|
const detail = error2 instanceof Error ? error2.message : String(error2);
|
|
29841
30231
|
return [`${CONTEXT} is not valid JSON: ${detail}.`];
|
|
29842
30232
|
}
|
|
29843
|
-
if (!
|
|
30233
|
+
if (!isObject15(state)) {
|
|
29844
30234
|
return [`${CONTEXT} root must be a JSON object.`];
|
|
29845
30235
|
}
|
|
29846
30236
|
const errors = [];
|
|
@@ -29918,7 +30308,7 @@ function validateIdentity2(state) {
|
|
|
29918
30308
|
const concurrency = state["max_concurrency"];
|
|
29919
30309
|
if ("max_concurrency" in state && !inBoundedRange(concurrency, MIN_CONCURRENCY2, MAX_CONCURRENCY2)) {
|
|
29920
30310
|
errors.push(
|
|
29921
|
-
`${CONTEXT2} max_concurrency must be an integer from ${MIN_CONCURRENCY2} through ${MAX_CONCURRENCY2}; found: ${
|
|
30311
|
+
`${CONTEXT2} max_concurrency must be an integer from ${MIN_CONCURRENCY2} through ${MAX_CONCURRENCY2}; found: ${pythonRepr10(concurrency)}.`
|
|
29922
30312
|
);
|
|
29923
30313
|
}
|
|
29924
30314
|
return errors;
|
|
@@ -29929,7 +30319,7 @@ function itemRecords(items) {
|
|
|
29929
30319
|
}
|
|
29930
30320
|
const records = [];
|
|
29931
30321
|
items.forEach((entry, index) => {
|
|
29932
|
-
if (
|
|
30322
|
+
if (isObject15(entry)) {
|
|
29933
30323
|
records.push({ index, record: entry });
|
|
29934
30324
|
}
|
|
29935
30325
|
});
|
|
@@ -29998,13 +30388,13 @@ function validateReadyItem(record3, entryContext) {
|
|
|
29998
30388
|
const preparationStatus = record3["preparation_status"];
|
|
29999
30389
|
if (preparationStatus !== READY_PREPARATION_STATUS) {
|
|
30000
30390
|
errors.push(
|
|
30001
|
-
`${entryContext} preparation_status must be ${
|
|
30391
|
+
`${entryContext} preparation_status must be ${pythonRepr10(READY_PREPARATION_STATUS)}; found: ${pythonRepr10(preparationStatus)}.`
|
|
30002
30392
|
);
|
|
30003
30393
|
}
|
|
30004
30394
|
const preflightStatus = record3["preflight_status"];
|
|
30005
30395
|
if (preflightStatus !== READY_PREFLIGHT_STATUS) {
|
|
30006
30396
|
errors.push(
|
|
30007
|
-
`${entryContext} preflight_status must be ${
|
|
30397
|
+
`${entryContext} preflight_status must be ${pythonRepr10(READY_PREFLIGHT_STATUS)}; found: ${pythonRepr10(preflightStatus)}.`
|
|
30008
30398
|
);
|
|
30009
30399
|
}
|
|
30010
30400
|
for (const key of READY_ITEM_PATH_KEYS) {
|
|
@@ -30013,10 +30403,10 @@ function validateReadyItem(record3, entryContext) {
|
|
|
30013
30403
|
}
|
|
30014
30404
|
}
|
|
30015
30405
|
const radius = record3["blast_radius"];
|
|
30016
|
-
const source =
|
|
30406
|
+
const source = isObject15(radius) ? radius["source"] : null;
|
|
30017
30407
|
if (source !== READY_RADIUS_SOURCE) {
|
|
30018
30408
|
errors.push(
|
|
30019
|
-
`${entryContext} blast_radius.source must be ${
|
|
30409
|
+
`${entryContext} blast_radius.source must be ${pythonRepr10(READY_RADIUS_SOURCE)} for execution readiness; found: ${pythonRepr10(source)}.`
|
|
30020
30410
|
);
|
|
30021
30411
|
}
|
|
30022
30412
|
return errors;
|
|
@@ -30038,14 +30428,14 @@ function validateReadyGate(state) {
|
|
|
30038
30428
|
const nextStep = state["next_step"];
|
|
30039
30429
|
if (nextStep !== READY_NEXT_STEP2) {
|
|
30040
30430
|
errors.push(
|
|
30041
|
-
`${CONTEXT2} next_step must be ${
|
|
30431
|
+
`${CONTEXT2} next_step must be ${pythonRepr10(READY_NEXT_STEP2)}; found: ${pythonRepr10(nextStep)}.`
|
|
30042
30432
|
);
|
|
30043
30433
|
}
|
|
30044
30434
|
const expectedKickoff = kickoffPathFor(state["parallel_slug"]);
|
|
30045
30435
|
const kickoffPromptPath = state["kickoff_prompt_path"];
|
|
30046
30436
|
if (kickoffPromptPath !== expectedKickoff) {
|
|
30047
30437
|
errors.push(
|
|
30048
|
-
`${CONTEXT2} kickoff_prompt_path must be ${
|
|
30438
|
+
`${CONTEXT2} kickoff_prompt_path must be ${pythonRepr10(expectedKickoff)}; found: ${pythonRepr10(kickoffPromptPath)}.`
|
|
30049
30439
|
);
|
|
30050
30440
|
}
|
|
30051
30441
|
return errors;
|
|
@@ -30058,7 +30448,7 @@ function validateParallelPlannerStateText(text2, options = {}) {
|
|
|
30058
30448
|
const detail = error2 instanceof Error ? error2.message : String(error2);
|
|
30059
30449
|
return [`${CONTEXT2} is not valid JSON: ${detail}.`];
|
|
30060
30450
|
}
|
|
30061
|
-
if (!
|
|
30451
|
+
if (!isObject15(state)) {
|
|
30062
30452
|
return [`${CONTEXT2} root must be a JSON object.`];
|
|
30063
30453
|
}
|
|
30064
30454
|
const errors = [];
|
|
@@ -35873,6 +36263,10 @@ function promotePotential(options) {
|
|
|
35873
36263
|
filesystem.ensureDir(promotedDir);
|
|
35874
36264
|
const destPath = posixJoin(promotedDir, posixBasename(resolved));
|
|
35875
36265
|
filesystem.move(resolved, destPath);
|
|
36266
|
+
if (!filesystem.exists(destPath)) {
|
|
36267
|
+
emitLine(`Promoted file missing after move: ${destPath}`);
|
|
36268
|
+
return { exitCode: 1, messages };
|
|
36269
|
+
}
|
|
35876
36270
|
emitLine(`Moved potential file to promoted folder: ${destPath}`);
|
|
35877
36271
|
return { exitCode: 0, messages, destination: destPath };
|
|
35878
36272
|
}
|