voidmachine 5.0.2 → 5.0.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.
- package/core-assets/.claude-plugin/plugin.json +1 -1
- package/core-assets/data/catalog.v3.json +8 -8
- package/core-assets/data/certification.json +1 -1
- package/core-assets/data/model.json +7 -7
- package/core-assets/hooks/_void-hook.mjs +80 -46
- package/core-assets/skills/void-autopilot/SKILL.md +14 -13
- package/core-assets/skills/void-implement/SKILL.md +2 -2
- package/core-assets/skills/void-orchestrate/SKILL.md +16 -0
- package/core-assets/skills/void-verify/.source +2 -0
- package/core-assets/skills/void-verify/SKILL.md +19 -0
- package/core-assets/skills/void-verify/references/ci-admission.mjs +25 -0
- package/core-assets/skills/void-verify/references/ci-feedback.md +51 -0
- package/core-assets/skills/void-verify/references/quality.yml +34 -0
- package/dist/main.js +215 -80
- package/package.json +2 -2
package/dist/main.js
CHANGED
|
@@ -35768,6 +35768,7 @@ init_esm_shims();
|
|
|
35768
35768
|
|
|
35769
35769
|
// ../mission-engine/dist/orchestration/review-loop.js
|
|
35770
35770
|
init_esm_shims();
|
|
35771
|
+
var BOUNDED_REVIEW_BUDGET = { maxRounds: 3, maxCorrectionBatches: 2 };
|
|
35771
35772
|
var SHA256 = /^sha256:[a-f0-9]{64}$/;
|
|
35772
35773
|
function validNativeContextId(value) {
|
|
35773
35774
|
return typeof value === "string" && value.trim().length > 0 && value.length <= 160 && [...value].every((char) => char.charCodeAt(0) >= 32 && (char.charCodeAt(0) < 127 || char.charCodeAt(0) > 159));
|
|
@@ -36579,6 +36580,92 @@ function opaqueNativeContextDefect(input2) {
|
|
|
36579
36580
|
return starts.length === 1 && started !== void 0 && started.source === event.source && started.seq > requested.seq && started.seq < event.seq && ["stage", "reviewRound", "inputHash", "contractVersion", "contextId"].every((key) => field4(started, key) === field4(event, key));
|
|
36580
36581
|
});
|
|
36581
36582
|
}
|
|
36583
|
+
function preparationInvocationReplacement(input2) {
|
|
36584
|
+
const { events } = input2.stream;
|
|
36585
|
+
const { observation: observation2, request } = input2;
|
|
36586
|
+
if (request.disposition.kind !== "preparation-invocation")
|
|
36587
|
+
return false;
|
|
36588
|
+
const start = events[0];
|
|
36589
|
+
const closure = events.at(-1);
|
|
36590
|
+
const writerRequests = events.filter((event) => event.kind === "lead-writer.requested");
|
|
36591
|
+
const writers = events.filter((event) => event.kind === "lead-writer.completed");
|
|
36592
|
+
const writer = writers[0];
|
|
36593
|
+
const writerRequest = writerRequests[0];
|
|
36594
|
+
if (start === void 0 || start.kind !== "mission.started" || start.source !== "void-harness:mission" || !["team", "fortress"].includes(String(field4(start, "mode"))) || field4(start, "runtimeAttested") !== true || `runtime:${String(field4(start, "runtime"))}` !== observation2.expectedSource || !/^sha256:[a-f0-9]{64}$/.test(String(field4(start, "planHash"))) || observation2.stage !== "pre-implementation" || observation2.maxRounds !== 2 || closure?.source !== "void-harness:mission.dispatch" || writer === void 0 || writerRequest === void 0 || writers.length !== 1 || writerRequests.length !== 1 || writerRequest.seq >= writer.seq || writerRequest.source !== "void-harness:mission.dispatch" || writer.subject !== field4(start, "leadWriterId") || writer.source !== writer.subject || writerRequest.subject !== writer.subject || writer.causationId !== writerRequest.eventId || field4(writer, "requestEventId") !== writerRequest.eventId || field4(writer, "actionKind") !== "run-preparation-correction" || field4(writer, "planHash") !== field4(start, "planHash") || field4(writer, "writerId") !== writer.subject || field4(writer, "implementationRound") !== 1 || !["actionKind", "planHash", "writerId", "implementationRound"].every((key) => field4(writer, key) === field4(writerRequest, key)))
|
|
36595
|
+
return false;
|
|
36596
|
+
const allowed = [
|
|
36597
|
+
"mission.started",
|
|
36598
|
+
"mission.closed",
|
|
36599
|
+
"lead-writer.requested",
|
|
36600
|
+
"lead-writer.completed",
|
|
36601
|
+
"specialist.requested",
|
|
36602
|
+
"specialist.started",
|
|
36603
|
+
"specialist.completed",
|
|
36604
|
+
"evidence.recorded",
|
|
36605
|
+
"specialist.evidence-classification-requested",
|
|
36606
|
+
"specialist.evidence-started",
|
|
36607
|
+
"specialist.evidence-classified",
|
|
36608
|
+
"specialist.evidence-discharge-requested",
|
|
36609
|
+
"specialist.evidence-discharged"
|
|
36610
|
+
];
|
|
36611
|
+
if (events.some((event) => !allowed.includes(event.kind)))
|
|
36612
|
+
return false;
|
|
36613
|
+
const required2 = Object.keys(observation2.contractVersions);
|
|
36614
|
+
const panel = completions(events);
|
|
36615
|
+
const invocations = events.filter((event) => ["specialist.requested", "specialist.started", "specialist.completed"].includes(event.kind));
|
|
36616
|
+
if (required2.length === 0 || panel.length !== required2.length * 2 || invocations.length !== panel.length * 3)
|
|
36617
|
+
return false;
|
|
36618
|
+
const ids = request.disposition.completionEventIds;
|
|
36619
|
+
if (ids.length === 0 || new Set(ids).size !== ids.length)
|
|
36620
|
+
return false;
|
|
36621
|
+
for (const specialist of required2) {
|
|
36622
|
+
for (const round of [1, 2]) {
|
|
36623
|
+
const matching = panel.filter((item2) => item2.event.subject === specialist && field4(item2.event, "reviewRound") === round);
|
|
36624
|
+
const item = matching[0];
|
|
36625
|
+
if (matching.length !== 1 || item === void 0)
|
|
36626
|
+
return false;
|
|
36627
|
+
const { event, completion } = item;
|
|
36628
|
+
if (event.source !== observation2.expectedSource || field4(event, "stage") !== "pre-implementation" || completion.specialistId !== specialist || completion.contractVersion !== observation2.contractVersions[specialist] || field4(event, "contractVersion") !== completion.contractVersion || !validNativeContextId(field4(event, "contextId")) || completion.verdict !== "pass" || completion.findings.length > 0 || round === 2 && (event.seq <= writer.seq || completion.evidenceRequests.length > 0 || field4(event, "inputHash") !== observation2.currentInputHashes[specialist]) || round === 1 && event.seq >= writerRequest.seq)
|
|
36629
|
+
return false;
|
|
36630
|
+
const requests = invocations.filter((candidate) => matchesRequest(event, candidate));
|
|
36631
|
+
const requested = requests[0];
|
|
36632
|
+
const starts = invocations.filter((candidate) => candidate.kind === "specialist.started" && candidate.subject === specialist && field4(candidate, "reviewRound") === round);
|
|
36633
|
+
const started = starts[0];
|
|
36634
|
+
if (requests.length !== 1 || starts.length !== 1 || requested === void 0 || started === void 0 || requested.seq >= started.seq || started.seq >= event.seq || round === 2 && requested.seq <= writer.seq || started.source !== observation2.expectedSource || field4(requested, "planHash") !== field4(start, "planHash") || field4(requested, "runtime") !== field4(start, "runtime") || field4(requested, "contractVersion") !== completion.contractVersion || !["stage", "reviewRound", "inputHash", "contractVersion", "contextId"].every((key) => field4(started, key) === field4(event, key)))
|
|
36635
|
+
return false;
|
|
36636
|
+
}
|
|
36637
|
+
}
|
|
36638
|
+
const proofs = events.flatMap((event) => {
|
|
36639
|
+
if (event.kind !== "evidence.recorded")
|
|
36640
|
+
return [];
|
|
36641
|
+
const parsed = parseEvidence(field4(event, "evidence"));
|
|
36642
|
+
return parsed.ok ? [{ eventId: event.eventId, evidence: parsed.value }] : [];
|
|
36643
|
+
});
|
|
36644
|
+
const obligations = reduceEvidenceObligations({
|
|
36645
|
+
events,
|
|
36646
|
+
expectedSource: observation2.expectedSource,
|
|
36647
|
+
phase: "pre-implementation",
|
|
36648
|
+
proofs,
|
|
36649
|
+
evidenceContext: {
|
|
36650
|
+
missionId: start.missionId,
|
|
36651
|
+
dependencies: observation2.evidenceDependencies ?? {}
|
|
36652
|
+
}
|
|
36653
|
+
});
|
|
36654
|
+
if (obligations.issues.length > 0 || obligations.blockingObligationIds.length > 0)
|
|
36655
|
+
return false;
|
|
36656
|
+
const review = reduceReviewLoop({
|
|
36657
|
+
events,
|
|
36658
|
+
stage: "pre-implementation",
|
|
36659
|
+
expectedSource: observation2.expectedSource,
|
|
36660
|
+
stageStartSeqExclusive: start.seq,
|
|
36661
|
+
afterSeqExclusive: writer.seq,
|
|
36662
|
+
requiredSpecialists: required2.filter(specialistId2),
|
|
36663
|
+
contractVersions: observation2.contractVersions,
|
|
36664
|
+
currentInputHashes: observation2.currentInputHashes,
|
|
36665
|
+
maxRounds: observation2.maxRounds
|
|
36666
|
+
});
|
|
36667
|
+
return review.issues.length === ids.length && review.issues.every((issue4) => issue4.code === "reused-context" && ids.includes(issue4.eventId) && events.some((event) => event.eventId === issue4.eventId && event.seq > writer.seq));
|
|
36668
|
+
}
|
|
36582
36669
|
function partialFanoutCorrections(events) {
|
|
36583
36670
|
if (events.some((event) => event.kind === "lead-writer.completed" || event.kind === "specialist.failed"))
|
|
36584
36671
|
return [];
|
|
@@ -36641,7 +36728,7 @@ function staleDispatchCompletions(events) {
|
|
|
36641
36728
|
function specialistId2(value) {
|
|
36642
36729
|
return /^core:[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value);
|
|
36643
36730
|
}
|
|
36644
|
-
function validProvenanceRecovery(input2, existing) {
|
|
36731
|
+
function validProvenanceRecovery(input2, existing, afterSeqExclusive = 0) {
|
|
36645
36732
|
const disposition = input2.request.disposition;
|
|
36646
36733
|
const observation2 = input2.observation;
|
|
36647
36734
|
const bindings = observation2.reviewBindings;
|
|
@@ -36655,10 +36742,10 @@ function validProvenanceRecovery(input2, existing) {
|
|
|
36655
36742
|
const observedSubject = observation2.reviewSubject;
|
|
36656
36743
|
return bindings.every((binding3) => {
|
|
36657
36744
|
const original = existing.find((item) => item.event.eventId === binding3.completionEventId);
|
|
36658
|
-
if (original === void 0 || !disposition.completionEventIds.includes(binding3.completionEventId) || original.event.subject !== "core:independent-code-reviewer" || original.event.source !== observation2.expectedSource || original.completion.verdict !== "pass" || original.completion.findings.some((finding) => finding.classification !== "advisory") || original.completion.contractVersion !== observation2.contractVersions[original.event.subject] || field4(original.event, "inputHash") !== observation2.currentInputHashes[original.event.subject] || canonicalJsonHash(original.completion) !== binding3.completionHash || !sameReviewSubject(binding3.review, observedSubject) || binding3.review.taskId !== original.event.missionId || binding3.review.writerId !== writerId || binding3.review.provenance.kind !== "native-context" || binding3.review.provenance.contextId !== field4(original.event, "contextId"))
|
|
36745
|
+
if (parseReviewReceipt(binding3.review) === void 0 || original === void 0 || original.event.seq <= afterSeqExclusive || !disposition.completionEventIds.includes(binding3.completionEventId) || original.event.subject !== "core:independent-code-reviewer" || original.event.source !== observation2.expectedSource || original.completion.verdict !== "pass" || original.completion.findings.some((finding) => finding.classification !== "advisory") || original.completion.contractVersion !== observation2.contractVersions[original.event.subject] || field4(original.event, "inputHash") !== observation2.currentInputHashes[original.event.subject] || canonicalJsonHash(original.completion) !== binding3.completionHash || !sameReviewSubject(binding3.review, observedSubject) || binding3.review.taskId !== original.event.missionId || binding3.review.writerId !== writerId || binding3.review.provenance.kind !== "native-context" || binding3.review.provenance.contextId !== field4(original.event, "contextId"))
|
|
36659
36746
|
return false;
|
|
36660
|
-
const requested = events.find((event) => event.seq < original.event.seq && matchesRequest(original.event, event) && field4(event, "contractVersion") === original.completion.contractVersion && `runtime:${String(field4(event, "runtime"))}` === observation2.expectedSource);
|
|
36661
|
-
return requested !== void 0 && events.some((event) => event.kind === "specialist.started" && event.source === observation2.expectedSource && event.subject === original.event.subject && event.seq > requested.seq && event.seq < original.event.seq && ["stage", "reviewRound", "inputHash", "contextId"].every((key) => field4(event, key) === field4(original.event, key)));
|
|
36747
|
+
const requested = events.find((event) => event.seq > afterSeqExclusive && event.seq < original.event.seq && matchesRequest(original.event, event) && field4(event, "contractVersion") === original.completion.contractVersion && `runtime:${String(field4(event, "runtime"))}` === observation2.expectedSource);
|
|
36748
|
+
return requested !== void 0 && events.some((event) => event.kind === "specialist.started" && event.source === observation2.expectedSource && event.subject === original.event.subject && event.seq > requested.seq && event.seq < original.event.seq && ["stage", "reviewRound", "inputHash", "contractVersion", "contextId"].every((key) => field4(event, key) === field4(original.event, key)));
|
|
36662
36749
|
});
|
|
36663
36750
|
}
|
|
36664
36751
|
function pendingPreparationClarification(input2, previousRecovery) {
|
|
@@ -36709,14 +36796,18 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
|
36709
36796
|
return refuse2("stale-journal", "Re-observe the journal before requesting recovery");
|
|
36710
36797
|
if (ambiguousEffects(events))
|
|
36711
36798
|
return refuse2("ambiguous-effect", "Reconcile the unfinished external effect; recovery cannot replay it");
|
|
36799
|
+
const existing = completions(events).filter((item) => field4(item.event, "stage") === observation2.stage);
|
|
36712
36800
|
const previousRecovery = events.filter((event) => event.kind === "mission.recovered").at(-1);
|
|
36713
|
-
if (previousRecovery !== void 0 && !events.some((event) => event.seq > previousRecovery.seq && event.kind === "lead-writer.completed") && !pendingPreparationClarification(input2, previousRecovery)) {
|
|
36801
|
+
if (previousRecovery !== void 0 && !events.some((event) => event.seq > previousRecovery.seq && event.kind === "lead-writer.completed") && !pendingPreparationClarification(input2, previousRecovery) && !validProvenanceRecovery(input2, existing, previousRecovery.seq)) {
|
|
36714
36802
|
return refuse2("no-recovery-progress", "Record actual corrective progress before reopening another stopped episode");
|
|
36715
36803
|
}
|
|
36716
|
-
const existing = completions(events).filter((item) => field4(item.event, "stage") === observation2.stage);
|
|
36717
|
-
const roundCorrections = partialFanoutCorrections(projectedHistory);
|
|
36718
|
-
const inadmissible = staleDispatchCompletions(projectedHistory);
|
|
36719
36804
|
const disposition = request.disposition;
|
|
36805
|
+
const replacement = disposition.kind === "preparation-invocation";
|
|
36806
|
+
if (replacement && !preparationInvocationReplacement(input2)) {
|
|
36807
|
+
return refuse2("invalid-preparation-invocation", "Name exactly the reused-context preparation completions with intact invocation bindings; replacement is one-time and retains round two");
|
|
36808
|
+
}
|
|
36809
|
+
const roundCorrections = replacement ? [] : partialFanoutCorrections(projectedHistory);
|
|
36810
|
+
const inadmissible = replacement ? disposition.completionEventIds : staleDispatchCompletions(projectedHistory);
|
|
36720
36811
|
if (disposition.kind === "controller-defect" && (disposition.defect === "partial-fanout-round" ? roundCorrections.length === 0 : disposition.defect === "stale-input-dispatch" ? inadmissible.length === 0 : !opaqueNativeContextDefect(input2))) {
|
|
36721
36812
|
return refuse2("unproven-controller-defect", "The journal must prove the requested controller defect; do not reset its budget");
|
|
36722
36813
|
}
|
|
@@ -36767,8 +36858,8 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
|
36767
36858
|
const projected = applyRoundCorrections(projectedHistory, roundCorrections).filter((event) => !inadmissible.includes(event.eventId));
|
|
36768
36859
|
const required2 = Object.keys(observation2.contractVersions).filter(specialistId2);
|
|
36769
36860
|
const writers = projected.filter((event) => event.kind === "lead-writer.completed");
|
|
36770
|
-
const stageStart = observation2.stage === "post-implementation" ? writers.find((event) => field4(event, "actionKind") !== "run-preparation-correction")?.seq : void 0;
|
|
36771
|
-
const lastWriter = observation2.stage === "post-implementation" ? writers.at(-1)?.seq : void 0;
|
|
36861
|
+
const stageStart = observation2.stage === "post-implementation" ? writers.find((event) => field4(event, "actionKind") !== "run-preparation-correction")?.seq : replacement ? events[0]?.seq : void 0;
|
|
36862
|
+
const lastWriter = observation2.stage === "post-implementation" || replacement ? writers.at(-1)?.seq : void 0;
|
|
36772
36863
|
const migration = validatedSpecialistContractMigrationBoundary(events);
|
|
36773
36864
|
if (!migration.ok)
|
|
36774
36865
|
return refuse2("invalid-migration-receipt", migration.reasons.join("; "));
|
|
@@ -36789,10 +36880,10 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
|
36789
36880
|
requiredSpecialists: required2,
|
|
36790
36881
|
contractVersions: observation2.contractVersions,
|
|
36791
36882
|
currentInputHashes: observation2.currentInputHashes,
|
|
36792
|
-
maxRounds: observation2.maxRounds
|
|
36883
|
+
...observation2.reviewPolicy === "bounded-corrections-v1" ? BOUNDED_REVIEW_BUDGET : { maxRounds: observation2.maxRounds }
|
|
36793
36884
|
};
|
|
36794
36885
|
const originalReview = reduceReviewLoop({ ...reviewInput, events: projectedHistory });
|
|
36795
|
-
if (originalReview.issues.some((issue4) => issue4.code !== "wrong-review-round")) {
|
|
36886
|
+
if (originalReview.issues.some((issue4) => replacement ? issue4.code !== "reused-context" || !inadmissible.includes(issue4.eventId) : issue4.code !== "wrong-review-round")) {
|
|
36796
36887
|
return refuse2("inconsistent-review", "Resolve inconsistent source, contract or context evidence before recovery");
|
|
36797
36888
|
}
|
|
36798
36889
|
const review = reduceReviewLoop({ ...reviewInput, events: projected });
|
|
@@ -36802,8 +36893,8 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
|
36802
36893
|
if (disposition.kind === "controller-defect" && disposition.defect === "opaque-native-context" && (!review.readyForVerdict || existing.length !== required2.length || required2.some((id3) => !existing.some((item) => item.event.subject === id3)))) {
|
|
36803
36894
|
return refuse2("incomplete-required-panel", "Every required preparation specialist must have its original matching PASS triplet before recovery");
|
|
36804
36895
|
}
|
|
36805
|
-
const consumedRounds = Math.max(0, ...projected.filter((event) => ["specialist.completed", "specialist.failed"].includes(event.kind) && field4(event, "stage") === observation2.stage).map((event) => Number(field4(event, "reviewRound"))));
|
|
36806
|
-
if (disposition.kind !== "review-provenance" && consumedRounds >=
|
|
36896
|
+
const consumedRounds = Math.max(0, ...(replacement ? projectedHistory : projected).filter((event) => ["specialist.completed", "specialist.failed"].includes(event.kind) && field4(event, "stage") === observation2.stage).map((event) => Number(field4(event, "reviewRound"))));
|
|
36897
|
+
if (!replacement && disposition.kind !== "review-provenance" && consumedRounds >= reviewInput.maxRounds)
|
|
36807
36898
|
return refuse2("review-budget-exhausted", "The real review budget is exhausted; recovery cannot reset it");
|
|
36808
36899
|
const consumedCorrectionBatches = projected.filter((event) => event.kind === "lead-writer.completed" && field4(event, "actionKind") === "run-correction").length;
|
|
36809
36900
|
if (disposition.kind === "review-provenance" && consumedCorrectionBatches > 2) {
|
|
@@ -36825,12 +36916,12 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
|
36825
36916
|
inadmissibleCompletionEventIds: inadmissible,
|
|
36826
36917
|
roundCorrections,
|
|
36827
36918
|
consumedRounds,
|
|
36828
|
-
remainingRounds: Math.max(0,
|
|
36829
|
-
|
|
36919
|
+
remainingRounds: Math.max(0, reviewInput.maxRounds - consumedRounds),
|
|
36920
|
+
...!replacement && disposition.kind !== "review-provenance" ? {} : {
|
|
36830
36921
|
consumedCorrectionBatches,
|
|
36831
36922
|
remainingCorrectionBatches: 2 - consumedCorrectionBatches
|
|
36832
36923
|
},
|
|
36833
|
-
nextAction: disposition.kind === "review-provenance" || disposition.kind === "command-correction" || disposition.kind === "controller-defect" && disposition.defect === "opaque-native-context" ? "verification" : disposition.kind === "review-blocker" ? "clarification" : "correction"
|
|
36924
|
+
nextAction: replacement || disposition.kind === "review-provenance" || disposition.kind === "command-correction" || disposition.kind === "controller-defect" && disposition.defect === "opaque-native-context" ? "verification" : disposition.kind === "review-blocker" ? "clarification" : "correction"
|
|
36834
36925
|
};
|
|
36835
36926
|
if (new TextEncoder().encode(canonicalJson(receipt2)).length > 16384) {
|
|
36836
36927
|
return refuse2("recovery-receipt-too-large", "Narrow the recovery scope to the supported bounded incident");
|
|
@@ -36847,6 +36938,9 @@ function recoveryRequest(value) {
|
|
|
36847
36938
|
if (value === void 0 || !record10(value) || !exactKeys2(value, ["schemaVersion", "closureEventId", "expectedJournalHash", "disposition"]) || value["schemaVersion"] !== 1 || typeof value["closureEventId"] !== "string" || typeof value["expectedJournalHash"] !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value["expectedJournalHash"]) || value["disposition"] === void 0 || !record10(value["disposition"]))
|
|
36848
36939
|
return false;
|
|
36849
36940
|
const disposition = value["disposition"];
|
|
36941
|
+
if (disposition["kind"] === "preparation-invocation") {
|
|
36942
|
+
return exactKeys2(disposition, ["kind", "completionEventIds"]) && Array.isArray(disposition["completionEventIds"]) && disposition["completionEventIds"].length > 0 && disposition["completionEventIds"].length <= 64 && disposition["completionEventIds"].every((item) => typeof item === "string" && /^evt_[A-Za-z0-9_-]{8,100}$/.test(item)) && new Set(disposition["completionEventIds"]).size === disposition["completionEventIds"].length;
|
|
36943
|
+
}
|
|
36850
36944
|
if (disposition["kind"] === "command-correction") {
|
|
36851
36945
|
return exactKeys2(disposition, ["kind", "pairs", "resolutionArtifact"]) && isCommandEvidenceCorrections(disposition["pairs"]) && artifact(disposition["resolutionArtifact"]);
|
|
36852
36946
|
}
|
|
@@ -36867,11 +36961,12 @@ function recoveryObservation(value) {
|
|
|
36867
36961
|
"currentInputHashes",
|
|
36868
36962
|
"maxRounds",
|
|
36869
36963
|
"expectedSource",
|
|
36964
|
+
...value["reviewPolicy"] === void 0 ? [] : ["reviewPolicy"],
|
|
36870
36965
|
...value["resolutionArtifact"] === void 0 ? [] : ["resolutionArtifact"],
|
|
36871
36966
|
...value["reviewSubject"] === void 0 ? [] : ["reviewSubject"],
|
|
36872
36967
|
...value["reviewBindings"] === void 0 ? [] : ["reviewBindings"],
|
|
36873
36968
|
...value["evidenceDependencies"] === void 0 ? [] : ["evidenceDependencies"]
|
|
36874
|
-
]) || !["pre-implementation", "post-implementation"].includes(String(value["stage"])) || !["runtime:codex", "runtime:claude"].includes(String(value["expectedSource"])) || typeof value["maxRounds"] !== "number" || !Number.isSafeInteger(value["maxRounds"]) || value["maxRounds"] < 1 || value["maxRounds"] > 8 || value["contractVersions"] === void 0 || !record10(value["contractVersions"]) || value["currentInputHashes"] === void 0 || !record10(value["currentInputHashes"]))
|
|
36969
|
+
]) || value["reviewPolicy"] !== void 0 && value["reviewPolicy"] !== "bounded-corrections-v1" || !["pre-implementation", "post-implementation"].includes(String(value["stage"])) || !["runtime:codex", "runtime:claude"].includes(String(value["expectedSource"])) || typeof value["maxRounds"] !== "number" || !Number.isSafeInteger(value["maxRounds"]) || value["maxRounds"] < 1 || value["maxRounds"] > 8 || value["contractVersions"] === void 0 || !record10(value["contractVersions"]) || value["currentInputHashes"] === void 0 || !record10(value["currentInputHashes"]))
|
|
36875
36970
|
return false;
|
|
36876
36971
|
return Object.keys(value["contractVersions"]).length <= 64 && Object.keys(value["currentInputHashes"]).length <= 64 && Object.entries(value["contractVersions"]).every(([key, version3]) => specialistId2(key) && typeof version3 === "number" && Number.isSafeInteger(version3) && version3 >= 1 && version3 <= 1e4) && Object.entries(value["currentInputHashes"]).every(([key, hash7]) => specialistId2(key) && typeof hash7 === "string" && /^sha256:[a-f0-9]{64}$/.test(hash7)) && (value["reviewSubject"] === void 0 || isReviewSubject(value["reviewSubject"])) && (value["reviewBindings"] === void 0 || Array.isArray(value["reviewBindings"]) && value["reviewBindings"].length <= 64 && value["reviewBindings"].every(reviewBinding)) && (value["resolutionArtifact"] === void 0 || artifact(value["resolutionArtifact"])) && (value["evidenceDependencies"] === void 0 || record10(value["evidenceDependencies"]) && Object.keys(value["evidenceDependencies"]).length <= 64 && Object.entries(value["evidenceDependencies"]).every(([key, hash7]) => key.length > 0 && key.length <= 500 && typeof hash7 === "string" && /^sha256:[a-f0-9]{64}$/.test(hash7)));
|
|
36877
36972
|
}
|
|
@@ -38725,10 +38820,13 @@ function recoveredPreparationTargets(events) {
|
|
|
38725
38820
|
const request = record15(payload?.["request"] ?? null);
|
|
38726
38821
|
const disposition = record15(request?.["disposition"] ?? null);
|
|
38727
38822
|
const ids = disposition?.["completionEventIds"];
|
|
38728
|
-
if (observation2?.["stage"] !== "pre-implementation" || disposition?.["kind"]
|
|
38823
|
+
if (observation2?.["stage"] !== "pre-implementation" || !["review-blocker", "preparation-invocation"].includes(String(disposition?.["kind"])) || !Array.isArray(ids))
|
|
38729
38824
|
return void 0;
|
|
38730
38825
|
return {
|
|
38731
38826
|
recoverySeq: recovery.seq,
|
|
38827
|
+
replacement: disposition?.["kind"] === "preparation-invocation",
|
|
38828
|
+
inputHashes: record15(observation2["currentInputHashes"] ?? {}) ?? {},
|
|
38829
|
+
contractVersions: record15(observation2["contractVersions"] ?? {}) ?? {},
|
|
38732
38830
|
specialistIds: events.filter((item) => item.kind === "specialist.completed" && ids.includes(item.eventId)).map((item) => item.subject)
|
|
38733
38831
|
};
|
|
38734
38832
|
}
|
|
@@ -38800,7 +38898,7 @@ function orchestrateMissionTeam(originalInput) {
|
|
|
38800
38898
|
const start = missionStart(input2);
|
|
38801
38899
|
const recovered = validatedRecoveredReviewEvents(input2.stream.events);
|
|
38802
38900
|
const reviewEvents = recovered.ok ? recovered.events : input2.stream.events;
|
|
38803
|
-
const preparationRecovery = recovered.ok ? recoveredPreparationTargets(
|
|
38901
|
+
const preparationRecovery = recovered.ok ? recoveredPreparationTargets(input2.stream.events) : void 0;
|
|
38804
38902
|
const writerEvents = writerCompletions(input2);
|
|
38805
38903
|
const preparationCorrections = writerEvents.filter((event) => lifecycleField(event, "actionKind") === "run-preparation-correction");
|
|
38806
38904
|
const completions2 = writerEvents.filter((event) => lifecycleField(event, "actionKind") !== "run-preparation-correction");
|
|
@@ -38885,6 +38983,9 @@ function orchestrateMissionTeam(originalInput) {
|
|
|
38885
38983
|
}
|
|
38886
38984
|
if (!migrated.ok)
|
|
38887
38985
|
return stopped("degraded", preReview, baseVerdict, migrated.reasons);
|
|
38986
|
+
if (preparationRecovery?.replacement && firstImplementationSeq === void 0 && requiredSpecialists(input2.plan, "pre-implementation").some((id3) => input2.currentInputHashesByStage["pre-implementation"][id3] !== preparationRecovery.inputHashes[id3] || contractVersions(input2.plan)[id3] !== preparationRecovery.contractVersions[id3])) {
|
|
38987
|
+
return stopped("blocked", preReview, baseVerdict, ["Preparation replacement inputs or contracts changed; reconcile the admitted subject before dispatch"]);
|
|
38988
|
+
}
|
|
38888
38989
|
const pendingEvidence = obligationStop(obligations, preReview, baseVerdict, firstImplementationSeq === void 0);
|
|
38889
38990
|
const migration = migrated.migration;
|
|
38890
38991
|
if (migration !== void 0) {
|
|
@@ -38916,7 +39017,7 @@ function orchestrateMissionTeam(originalInput) {
|
|
|
38916
39017
|
if (pendingEvidence !== void 0 && !correctiveContinuation) {
|
|
38917
39018
|
return applyRuntimeCertification(pendingEvidence, input2.specialistRuntime);
|
|
38918
39019
|
}
|
|
38919
|
-
if (preparationRecovery !== void 0 && (lastPreparationSeq === void 0 || lastPreparationSeq < preparationRecovery.recoverySeq)) {
|
|
39020
|
+
if (preparationRecovery !== void 0 && !preparationRecovery.replacement && (lastPreparationSeq === void 0 || lastPreparationSeq < preparationRecovery.recoverySeq)) {
|
|
38920
39021
|
if (preReview.issues.length > 0) {
|
|
38921
39022
|
return decideReviewPhase(start, preReview, baseVerdict, "pre-implementation");
|
|
38922
39023
|
}
|
|
@@ -38971,8 +39072,7 @@ function orchestrateMissionTeam(originalInput) {
|
|
|
38971
39072
|
requiredSpecialists: requiredSpecialists(input2.plan, "post-implementation", start.boundedReview),
|
|
38972
39073
|
contractVersions: contractVersions(input2.plan),
|
|
38973
39074
|
currentInputHashes: input2.currentInputHashesByStage["post-implementation"],
|
|
38974
|
-
|
|
38975
|
-
...start.boundedReview ? { maxCorrectionBatches: 2 } : {},
|
|
39075
|
+
...start.boundedReview ? BOUNDED_REVIEW_BUDGET : { maxRounds: input2.maxReviewRounds },
|
|
38976
39076
|
evidenceObligations: obligations,
|
|
38977
39077
|
validProofIds: input2.stream.events.flatMap((event) => {
|
|
38978
39078
|
if (event.kind !== "evidence.recorded")
|
|
@@ -46479,7 +46579,7 @@ function dependencyEntries(pkg) {
|
|
|
46479
46579
|
function technology(id3, version3, source2) {
|
|
46480
46580
|
return Object.freeze({ id: id3, version: version3, sources: Object.freeze([source2]) });
|
|
46481
46581
|
}
|
|
46482
|
-
function packageTechnologies(workspace) {
|
|
46582
|
+
function packageTechnologies(workspace, recipe) {
|
|
46483
46583
|
const technologies = /* @__PURE__ */ new Map();
|
|
46484
46584
|
const source2 = workspace.path === "." ? "package.json" : `${workspace.path}/package.json`;
|
|
46485
46585
|
for (const [dependency, version3] of dependencyEntries(workspace.packageJson)) {
|
|
@@ -46492,7 +46592,10 @@ function packageTechnologies(workspace) {
|
|
|
46492
46592
|
}
|
|
46493
46593
|
}
|
|
46494
46594
|
if (workspace.path === ".") {
|
|
46495
|
-
|
|
46595
|
+
const declaredNode2 = workspace.packageJson.engines?.node;
|
|
46596
|
+
const projectNode = typeof declaredNode2 === "string" && /^\d+\.\d+\.\d+$/.test(declaredNode2) ? declaredNode2 : null;
|
|
46597
|
+
const projectNodeSource = projectNode === null && typeof declaredNode2 === "string" ? `package.json:engines.node:${declaredNode2}` : "package.json:engines.node";
|
|
46598
|
+
technologies.set("node", recipe === "runtime-v1" ? technology("node", exactVersion(process.versions.node), "runtime:node") : technology("node", projectNode, projectNodeSource));
|
|
46496
46599
|
const packageManager = workspace.packageJson.packageManager;
|
|
46497
46600
|
if (packageManager !== void 0) {
|
|
46498
46601
|
const separator = packageManager.indexOf("@");
|
|
@@ -46518,7 +46621,7 @@ function packageTechnologies(workspace) {
|
|
|
46518
46621
|
function validChangedFile(file2) {
|
|
46519
46622
|
return file2.length > 0 && !file2.startsWith("/") && !file2.startsWith("../") && !file2.includes("/../") && !file2.includes("\\") && posix.normalize(file2) === file2;
|
|
46520
46623
|
}
|
|
46521
|
-
function detectProfileInput(root, files) {
|
|
46624
|
+
function detectProfileInput(root, files, recipe = "runtime-v1") {
|
|
46522
46625
|
if (!files.every(validChangedFile)) {
|
|
46523
46626
|
throw new Error("PROFILE_INPUT_INVALID: changed files must remain inside the project root");
|
|
46524
46627
|
}
|
|
@@ -46526,7 +46629,7 @@ function detectProfileInput(root, files) {
|
|
|
46526
46629
|
const rootWorkspace = workspaces.find((workspace) => workspace.path === ".");
|
|
46527
46630
|
const projects2 = workspaces.map((workspace) => Object.freeze({
|
|
46528
46631
|
path: workspace.path,
|
|
46529
|
-
technologies: packageTechnologies(workspace)
|
|
46632
|
+
technologies: packageTechnologies(workspace, recipe)
|
|
46530
46633
|
}));
|
|
46531
46634
|
if (projects2.length > 1) {
|
|
46532
46635
|
const rootProject = projects2.find((project) => project.path === ".");
|
|
@@ -55764,17 +55867,18 @@ async function createMission(root, input2) {
|
|
|
55764
55867
|
);
|
|
55765
55868
|
await writeMissionMetadata(run2, safeInput, createdAt);
|
|
55766
55869
|
}
|
|
55767
|
-
async function writeMissionControllerPlan(root, missionId, plan2, ticket, baseCommit) {
|
|
55870
|
+
async function writeMissionControllerPlan(root, missionId, plan2, ticket, baseCommit, inputRecipe) {
|
|
55768
55871
|
const run2 = await existingRunDirectory(root, missionId);
|
|
55769
|
-
const routingHash = missionControllerRoutingHash(plan2, ticket, baseCommit);
|
|
55872
|
+
const routingHash = missionControllerRoutingHash(plan2, ticket, baseCommit, inputRecipe);
|
|
55770
55873
|
const handle3 = await open$1(join(run2, "controller-plan.json"), "wx", 384);
|
|
55771
55874
|
try {
|
|
55772
55875
|
await handle3.writeFile(`${JSON.stringify({
|
|
55773
|
-
schemaVersion: baseCommit === void 0 ? 1 : 2,
|
|
55876
|
+
schemaVersion: inputRecipe === void 0 ? baseCommit === void 0 ? 1 : 2 : 3,
|
|
55774
55877
|
routingHash,
|
|
55775
55878
|
plan: plan2,
|
|
55776
55879
|
ticket,
|
|
55777
|
-
...baseCommit === void 0 ? {} : { baseCommit }
|
|
55880
|
+
...baseCommit === void 0 ? {} : { baseCommit },
|
|
55881
|
+
...inputRecipe === void 0 ? {} : { inputRecipe }
|
|
55778
55882
|
})}
|
|
55779
55883
|
`, "utf8");
|
|
55780
55884
|
} finally {
|
|
@@ -55803,28 +55907,38 @@ async function loadMissionControllerPlan(root, missionId) {
|
|
|
55803
55907
|
"routingHash",
|
|
55804
55908
|
"plan",
|
|
55805
55909
|
"ticket",
|
|
55806
|
-
...parsed.schemaVersion === 2 ? ["baseCommit"] : []
|
|
55910
|
+
...parsed.schemaVersion === 2 || parsed.schemaVersion === 3 ? ["baseCommit"] : [],
|
|
55911
|
+
...parsed.schemaVersion === 3 ? ["inputRecipe"] : []
|
|
55807
55912
|
])) {
|
|
55808
55913
|
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: plan envelope is malformed");
|
|
55809
55914
|
}
|
|
55810
55915
|
const plan2 = parseMissionSpecialistPlan(parsed.plan);
|
|
55811
55916
|
const ticket = parseMissionControllerTicket(parsed.ticket);
|
|
55812
55917
|
const routingHash = typeof parsed.routingHash === "string" ? parsed.routingHash : "";
|
|
55813
|
-
const baseCommit = parsed.schemaVersion === 2 ? parsed.baseCommit : void 0;
|
|
55814
|
-
|
|
55918
|
+
const baseCommit = parsed.schemaVersion === 2 || parsed.schemaVersion === 3 ? parsed.baseCommit : void 0;
|
|
55919
|
+
const inputRecipe = parsed.schemaVersion === 3 && parsed.inputRecipe === "project-v1" ? "project-v1" : void 0;
|
|
55920
|
+
if (parsed.schemaVersion !== 1 && parsed.schemaVersion !== 2 && parsed.schemaVersion !== 3 || parsed.schemaVersion === 3 && inputRecipe === void 0 || (parsed.schemaVersion === 2 || parsed.schemaVersion === 3) && (typeof baseCommit !== "string" || !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(baseCommit)) || !/^sha256:[a-f0-9]{64}$/.test(routingHash)) {
|
|
55815
55921
|
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: plan integrity check failed");
|
|
55816
55922
|
}
|
|
55817
55923
|
const base = typeof baseCommit === "string" ? { baseCommit } : {};
|
|
55818
|
-
if (missionControllerRoutingHash(plan2, ticket, base.baseCommit) !== routingHash) {
|
|
55924
|
+
if (missionControllerRoutingHash(plan2, ticket, base.baseCommit, inputRecipe) !== routingHash) {
|
|
55819
55925
|
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: plan integrity check failed");
|
|
55820
55926
|
}
|
|
55821
|
-
return Object.freeze({ plan: plan2, ticket, routingHash, ...base });
|
|
55927
|
+
return Object.freeze({ plan: plan2, ticket, routingHash, ...base, ...inputRecipe === void 0 ? {} : { inputRecipe } });
|
|
55822
55928
|
}
|
|
55823
|
-
function missionControllerRoutingHash(plan2, ticket, baseCommit) {
|
|
55929
|
+
function missionControllerRoutingHash(plan2, ticket, baseCommit, inputRecipe) {
|
|
55930
|
+
if (inputRecipe !== void 0 && (inputRecipe !== "project-v1" || baseCommit === void 0)) {
|
|
55931
|
+
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: project input recipe requires a committed baseline");
|
|
55932
|
+
}
|
|
55824
55933
|
if (baseCommit !== void 0 && !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(baseCommit)) {
|
|
55825
55934
|
throw new Error("MISSION_REVIEW_BASE_INVALID: expected a full commit object ID");
|
|
55826
55935
|
}
|
|
55827
|
-
return canonicalJsonHash({
|
|
55936
|
+
return canonicalJsonHash({
|
|
55937
|
+
plan: plan2,
|
|
55938
|
+
ticket,
|
|
55939
|
+
...baseCommit === void 0 ? {} : { baseCommit },
|
|
55940
|
+
...inputRecipe === void 0 ? {} : { inputRecipe }
|
|
55941
|
+
});
|
|
55828
55942
|
}
|
|
55829
55943
|
function unknownRecord2(value) {
|
|
55830
55944
|
return typeof value === "object" && Boolean(value) && !Array.isArray(value);
|
|
@@ -56236,6 +56350,7 @@ async function loadProfiles(root, coreProfileDirectory) {
|
|
|
56236
56350
|
// src/lib/mission-inputs.ts
|
|
56237
56351
|
var execFile2 = promisify(execFile);
|
|
56238
56352
|
var MAX_TICKET_BYTES = 1e5;
|
|
56353
|
+
var MAX_REVIEW_PATCH_BYTES = 16e6;
|
|
56239
56354
|
async function readTicket(root, ticketPath) {
|
|
56240
56355
|
const canonicalRoot = await realpath(resolve(root));
|
|
56241
56356
|
const loaded = await readBoundedProjectFile({
|
|
@@ -56291,7 +56406,7 @@ async function missionReviewBase(root) {
|
|
|
56291
56406
|
throw new Error("MISSION_REVIEW_BASE_INVALID: a committed Git baseline is required");
|
|
56292
56407
|
}
|
|
56293
56408
|
}
|
|
56294
|
-
async function captureMissionReviewSubject(root, baseCommit, committed = false) {
|
|
56409
|
+
async function captureMissionReviewSubject(root, baseCommit, committed = false, hashFormat = committed ? "committed" : "legacy") {
|
|
56295
56410
|
if (baseCommit === void 0) {
|
|
56296
56411
|
throw new Error(
|
|
56297
56412
|
"MISSION_REVIEW_BASE_MISSING: legacy mission has no review baseline; preserve its history and start a new mission"
|
|
@@ -56331,7 +56446,17 @@ async function captureMissionReviewSubject(root, baseCommit, committed = false)
|
|
|
56331
56446
|
"--relative",
|
|
56332
56447
|
...range,
|
|
56333
56448
|
...paths
|
|
56334
|
-
],
|
|
56449
|
+
], {
|
|
56450
|
+
...options2,
|
|
56451
|
+
maxBuffer: MAX_REVIEW_PATCH_BYTES
|
|
56452
|
+
}).catch((error62) => {
|
|
56453
|
+
if (error62 instanceof Error && "code" in error62 && error62.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") {
|
|
56454
|
+
throw new Error(
|
|
56455
|
+
`MISSION_REVIEW_PATCH_TOO_LARGE: Git review patch exceeds ${MAX_REVIEW_PATCH_BYTES} bytes`
|
|
56456
|
+
);
|
|
56457
|
+
}
|
|
56458
|
+
throw error62;
|
|
56459
|
+
}),
|
|
56335
56460
|
execFile2("git", [
|
|
56336
56461
|
"diff",
|
|
56337
56462
|
"--no-ext-diff",
|
|
@@ -56364,7 +56489,7 @@ async function captureMissionReviewSubject(root, baseCommit, committed = false)
|
|
|
56364
56489
|
files,
|
|
56365
56490
|
hash: canonicalJsonHash({
|
|
56366
56491
|
baseCommit,
|
|
56367
|
-
...
|
|
56492
|
+
...hashFormat === "legacy" ? {} : { reviewedCommit },
|
|
56368
56493
|
diff: patch.stdout,
|
|
56369
56494
|
files: files.files
|
|
56370
56495
|
})
|
|
@@ -56438,10 +56563,10 @@ function detectedStack(root, profileInput) {
|
|
|
56438
56563
|
status: "known"
|
|
56439
56564
|
});
|
|
56440
56565
|
}
|
|
56441
|
-
async function planMission(root, ticketPath, generatedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
56442
|
-
return (await planBoundMission(root, ticketPath, generatedAt)).plan;
|
|
56566
|
+
async function planMission(root, ticketPath, generatedAt = (/* @__PURE__ */ new Date()).toISOString(), inputRecipe = "runtime-v1") {
|
|
56567
|
+
return (await planBoundMission(root, ticketPath, generatedAt, void 0, void 0, inputRecipe)).plan;
|
|
56443
56568
|
}
|
|
56444
|
-
async function compileMission(root, ticket, generatedAt, detectedFiles, specialistCatalog) {
|
|
56569
|
+
async function compileMission(root, ticket, generatedAt, detectedFiles, specialistCatalog, inputRecipe = "runtime-v1") {
|
|
56445
56570
|
const [coreRoot, diff] = await Promise.all([
|
|
56446
56571
|
findCoreSource(),
|
|
56447
56572
|
detectedFiles ?? gitFiles(root)
|
|
@@ -56451,7 +56576,7 @@ async function compileMission(root, ticket, generatedAt, detectedFiles, speciali
|
|
|
56451
56576
|
loadProfiles(root, join(coreRoot, "profiles")),
|
|
56452
56577
|
specialistCatalog ?? loadSpecialists(coreRoot)
|
|
56453
56578
|
]);
|
|
56454
|
-
const profileInput = detectProfileInput(root, diff.files);
|
|
56579
|
+
const profileInput = detectProfileInput(root, diff.files, inputRecipe);
|
|
56455
56580
|
const stack = detectedStack(root, profileInput);
|
|
56456
56581
|
return compileMissionPlan({
|
|
56457
56582
|
ticket: { id: ticket.id, title: ticket.title, body: ticket.body },
|
|
@@ -56471,9 +56596,9 @@ function controllerTicketBinding(ticket) {
|
|
|
56471
56596
|
contentHash: `sha256:${createHash("sha256").update(ticket.body).digest("hex")}`
|
|
56472
56597
|
});
|
|
56473
56598
|
}
|
|
56474
|
-
async function planBoundMission(root, ticketPath, generatedAt = (/* @__PURE__ */ new Date()).toISOString(), detectedFiles, specialistCatalog) {
|
|
56599
|
+
async function planBoundMission(root, ticketPath, generatedAt = (/* @__PURE__ */ new Date()).toISOString(), detectedFiles, specialistCatalog, inputRecipe = "runtime-v1") {
|
|
56475
56600
|
const ticket = await readTicket(root, ticketPath);
|
|
56476
|
-
const plan2 = await compileMission(root, ticket, generatedAt, detectedFiles, specialistCatalog);
|
|
56601
|
+
const plan2 = await compileMission(root, ticket, generatedAt, detectedFiles, specialistCatalog, inputRecipe);
|
|
56477
56602
|
return Object.freeze({
|
|
56478
56603
|
plan: plan2,
|
|
56479
56604
|
ticket: controllerTicketBinding(ticket)
|
|
@@ -67040,6 +67165,10 @@ function parseMissionRecoveryRequest(value) {
|
|
|
67040
67165
|
}
|
|
67041
67166
|
const commandCorrection = disposition["kind"] === "command-correction";
|
|
67042
67167
|
const ids = disposition["completionEventIds"];
|
|
67168
|
+
if (disposition["kind"] === "preparation-invocation") {
|
|
67169
|
+
if (!exact2(disposition, ["kind", "completionEventIds"]) || !Array.isArray(ids) || ids.length < 1 || ids.length > 64 || !ids.every(eventId) || new Set(ids).size !== ids.length) invalid11();
|
|
67170
|
+
return { ...base, disposition: { kind: "preparation-invocation", completionEventIds: ids } };
|
|
67171
|
+
}
|
|
67043
67172
|
const artifact2 = disposition["resolutionArtifact"];
|
|
67044
67173
|
if (!commandCorrection && disposition["kind"] !== "review-blocker" && disposition["kind"] !== "review-provenance" || !exact2(disposition, ["kind", commandCorrection ? "pairs" : "completionEventIds", "resolutionArtifact"]) || !record24(artifact2) || !exact2(artifact2, ["path", "sha256"]) || typeof artifact2["path"] !== "string" || artifact2["path"].length < 1 || artifact2["path"].length > 500 || artifact2["path"].includes("\0") || /^(?:[A-Za-z]:|[/\\])/.test(artifact2["path"]) || artifact2["path"].replaceAll("\\", "/").split("/").includes("..") || !hash4(artifact2["sha256"])) invalid11();
|
|
67045
67174
|
if (commandCorrection) {
|
|
@@ -67817,7 +67946,7 @@ async function recordSpecialistRequests(root, missionId, envelopes, planHash) {
|
|
|
67817
67946
|
init_esm_shims();
|
|
67818
67947
|
|
|
67819
67948
|
// package.json
|
|
67820
|
-
var version2 = "5.0.
|
|
67949
|
+
var version2 = "5.0.4";
|
|
67821
67950
|
|
|
67822
67951
|
// src/lib/runs/verify.ts
|
|
67823
67952
|
var MAX_CAPTURE_BYTES = 64 * 1024;
|
|
@@ -68327,8 +68456,8 @@ async function migrateMissionSpecialist(roots, missionId, request) {
|
|
|
68327
68456
|
throw new Error(`SPECIALIST_CONTRACT_MIGRATION_NATIVE: ${capability.limitations.join("; ")}`);
|
|
68328
68457
|
}
|
|
68329
68458
|
const assets = await observeSpecialistMigrationAssets(coreRoot, installRoot, identity2.runtime);
|
|
68330
|
-
const subject = await
|
|
68331
|
-
const live = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files);
|
|
68459
|
+
const subject = await captureControllerReviewSubject(workRoot, stored.baseCommit, current.inspected.stream.events);
|
|
68460
|
+
const live = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, void 0, stored.inputRecipe);
|
|
68332
68461
|
if (live.ticket.path !== stored.ticket.path || live.ticket.contentHash !== stored.ticket.contentHash) {
|
|
68333
68462
|
throw new Error("MISSION_TICKET_CHANGED: migration cannot replace the bound ticket");
|
|
68334
68463
|
}
|
|
@@ -68337,7 +68466,7 @@ async function migrateMissionSpecialist(roots, missionId, request) {
|
|
|
68337
68466
|
canonicalJsonHash({ routing: specialist.proof.inputHash, subject: subject.hash })
|
|
68338
68467
|
]));
|
|
68339
68468
|
const comparisonCatalog = await loadSpecialistMigrationComparisonCatalog(coreRoot, assets.declaration, stored.plan);
|
|
68340
|
-
const comparison = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, comparisonCatalog);
|
|
68469
|
+
const comparison = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, comparisonCatalog, stored.inputRecipe);
|
|
68341
68470
|
const originalHashes = Object.fromEntries(comparison.plan.specialists.map((specialist) => [
|
|
68342
68471
|
specialist.specialistId,
|
|
68343
68472
|
canonicalJsonHash({ routing: specialist.proof.inputHash, subject: subject.hash })
|
|
@@ -68362,6 +68491,18 @@ async function migrateMissionSpecialist(roots, missionId, request) {
|
|
|
68362
68491
|
nativeAgentSha256: assets.nativeAgentSha256
|
|
68363
68492
|
} };
|
|
68364
68493
|
}
|
|
68494
|
+
function boundedMissionReview(events) {
|
|
68495
|
+
return events.some((event) => event.kind === "mission.started" && objectField(event.payload, "reviewPolicy") === "bounded-corrections-v1") || events.some((event) => event.kind === "mission.recovered" && objectField(objectField(objectField(event.payload, "request"), "disposition"), "kind") === "review-provenance");
|
|
68496
|
+
}
|
|
68497
|
+
function captureControllerReviewSubject(root, baseCommit, events, requireCommitted = false) {
|
|
68498
|
+
const committedFormat = events.some((event) => event.kind === "mission.started" && objectField(event.payload, "reviewPolicy") === "bounded-corrections-v1");
|
|
68499
|
+
return captureMissionReviewSubject(
|
|
68500
|
+
root,
|
|
68501
|
+
baseCommit,
|
|
68502
|
+
requireCommitted || boundedMissionReview(events),
|
|
68503
|
+
committedFormat ? "committed" : "legacy"
|
|
68504
|
+
);
|
|
68505
|
+
}
|
|
68365
68506
|
async function recoverStoppedMission(roots, missionId, request) {
|
|
68366
68507
|
const { workRoot, installRoot } = roots;
|
|
68367
68508
|
const [stored, current, coreRoot] = await Promise.all([
|
|
@@ -68393,8 +68534,13 @@ async function recoverStoppedMission(roots, missionId, request) {
|
|
|
68393
68534
|
}
|
|
68394
68535
|
}
|
|
68395
68536
|
const implemented = inspected.stream.events.some((event) => event.kind === "lead-writer.completed" && objectField(event.payload, "actionKind") !== "run-preparation-correction");
|
|
68396
|
-
const subject = implemented ? await
|
|
68397
|
-
|
|
68537
|
+
const subject = implemented ? await captureControllerReviewSubject(
|
|
68538
|
+
workRoot,
|
|
68539
|
+
stored.baseCommit,
|
|
68540
|
+
inspected.stream.events,
|
|
68541
|
+
provenanceRecovery
|
|
68542
|
+
) : void 0;
|
|
68543
|
+
const live = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject?.files, void 0, stored.inputRecipe);
|
|
68398
68544
|
if (live.ticket.path !== stored.ticket.path || live.ticket.contentHash !== stored.ticket.contentHash) {
|
|
68399
68545
|
throw new Error("MISSION_TICKET_CHANGED: recovery cannot replace the original ticket");
|
|
68400
68546
|
}
|
|
@@ -68411,7 +68557,7 @@ async function recoverStoppedMission(roots, missionId, request) {
|
|
|
68411
68557
|
throw new Error("SPECIALIST_CONTRACT_MIGRATION_INVALID: declared or installed contract changed");
|
|
68412
68558
|
}
|
|
68413
68559
|
const comparisonCatalog = await loadSpecialistMigrationComparisonCatalog(coreRoot, assets.declaration, stored.plan);
|
|
68414
|
-
const comparison = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, comparisonCatalog);
|
|
68560
|
+
const comparison = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, comparisonCatalog, stored.inputRecipe);
|
|
68415
68561
|
for (const specialist of comparison.plan.specialists) {
|
|
68416
68562
|
if (specialist.specialistId !== assets.declaration.specialistId) {
|
|
68417
68563
|
currentInputHashes[specialist.specialistId] = canonicalJsonHash({
|
|
@@ -68423,19 +68569,19 @@ async function recoverStoppedMission(roots, missionId, request) {
|
|
|
68423
68569
|
}
|
|
68424
68570
|
const provenance4 = request.disposition.kind !== "review-provenance" ? void 0 : await readRecoveryReviewBindings(workRoot, request.disposition.resolutionArtifact.path);
|
|
68425
68571
|
const resolutionArtifact = provenance4?.artifact ?? (request.disposition.kind === "review-blocker" || request.disposition.kind === "command-correction" ? await recoveryResolutionArtifact(workRoot, request.disposition.resolutionArtifact.path) : void 0);
|
|
68426
|
-
const committedSubject = provenance4 === void 0 ? void 0 : await captureMissionReviewSubject(workRoot, stored.baseCommit, true);
|
|
68427
68572
|
const opaqueContextRecovery = request.disposition.kind === "controller-defect" && request.disposition.defect === "opaque-native-context";
|
|
68428
|
-
const recoverySpecialists = opaqueContextRecovery ? migration.plan.specialists.filter((value) => value.state === "applicable" && value.stages?.includes("pre-implementation")) : migration.plan.specialists;
|
|
68573
|
+
const recoverySpecialists = opaqueContextRecovery || request.disposition.kind === "preparation-invocation" ? migration.plan.specialists.filter((value) => value.state === "applicable" && value.stages?.includes("pre-implementation")) : migration.plan.specialists;
|
|
68429
68574
|
const observation2 = {
|
|
68430
|
-
...provenance4 === void 0 ||
|
|
68575
|
+
...provenance4 === void 0 || subject?.baseCommit === void 0 || subject.reviewedCommit === void 0 ? {} : {
|
|
68431
68576
|
reviewBindings: provenance4.bindings,
|
|
68432
68577
|
reviewSubject: {
|
|
68433
68578
|
taskId: missionId,
|
|
68434
|
-
baseCommit:
|
|
68435
|
-
reviewedCommit:
|
|
68579
|
+
baseCommit: subject.baseCommit,
|
|
68580
|
+
reviewedCommit: subject.reviewedCommit,
|
|
68436
68581
|
acceptanceCriteriaHash: stored.ticket.contentHash
|
|
68437
68582
|
}
|
|
68438
68583
|
},
|
|
68584
|
+
...implemented && (provenanceRecovery || boundedMissionReview(inspected.stream.events)) ? { reviewPolicy: "bounded-corrections-v1" } : {},
|
|
68439
68585
|
stage: implemented ? "post-implementation" : "pre-implementation",
|
|
68440
68586
|
maxRounds: 2,
|
|
68441
68587
|
evidenceDependencies: { "git:working-tree": current.project.diffHash },
|
|
@@ -68499,13 +68645,14 @@ async function dispatchMissionSpecialists(roots, input2, generatedAt = (/* @__PU
|
|
|
68499
68645
|
const inspected = current?.inspected ?? initialInspection;
|
|
68500
68646
|
requireOpenMission(inspected.stream.events);
|
|
68501
68647
|
const implemented = inspected.stream.events.some((event) => event.kind === "lead-writer.completed" && isUnknownRecord(event.payload) && event.payload.actionKind !== "run-preparation-correction");
|
|
68502
|
-
const
|
|
68503
|
-
const reviewSubject = implemented ? await captureMissionReviewSubject(workRoot, stored.baseCommit, boundedReview) : void 0;
|
|
68648
|
+
const reviewSubject = implemented ? await captureControllerReviewSubject(workRoot, stored.baseCommit, inspected.stream.events) : void 0;
|
|
68504
68649
|
const live = await planBoundMission(
|
|
68505
68650
|
workRoot,
|
|
68506
68651
|
stored.ticket.path,
|
|
68507
68652
|
generatedAt,
|
|
68508
|
-
reviewSubject?.files
|
|
68653
|
+
reviewSubject?.files,
|
|
68654
|
+
void 0,
|
|
68655
|
+
stored.inputRecipe
|
|
68509
68656
|
);
|
|
68510
68657
|
const livePlan = live.plan;
|
|
68511
68658
|
if (live.ticket.path !== stored.ticket.path || live.ticket.contentHash !== stored.ticket.contentHash) {
|
|
@@ -68536,7 +68683,7 @@ async function dispatchMissionSpecialists(roots, input2, generatedAt = (/* @__PU
|
|
|
68536
68683
|
throw new Error("SPECIALIST_CONTRACT_MIGRATION_INVALID: declared or installed contract changed");
|
|
68537
68684
|
}
|
|
68538
68685
|
const catalog = await loadSpecialistMigrationComparisonCatalog(coreRoot, assets.declaration, stored.plan);
|
|
68539
|
-
const comparison = await planBoundMission(workRoot, stored.ticket.path, generatedAt, reviewSubject.files, catalog);
|
|
68686
|
+
const comparison = await planBoundMission(workRoot, stored.ticket.path, generatedAt, reviewSubject.files, catalog, stored.inputRecipe);
|
|
68540
68687
|
for (const specialist of comparison.plan.specialists) {
|
|
68541
68688
|
if (specialist.specialistId !== assets.declaration.specialistId) {
|
|
68542
68689
|
currentInputHashes[specialist.specialistId] = canonicalJsonHash({
|
|
@@ -68571,19 +68718,6 @@ async function dispatchMissionSpecialists(roots, input2, generatedAt = (/* @__PU
|
|
|
68571
68718
|
reviewedCommit: reviewSubject.reviewedCommit,
|
|
68572
68719
|
acceptanceCriteriaHash: stored.ticket.contentHash
|
|
68573
68720
|
};
|
|
68574
|
-
if (reviewBinding2 !== void 0) {
|
|
68575
|
-
const restored = validatedRecoveredReviewEvents(inspected.stream.events);
|
|
68576
|
-
if (!restored.ok) throw new Error(`MISSION_RECOVERY_INVALID: ${restored.reasons.join("; ")}`);
|
|
68577
|
-
const hasProvenanceRecovery = inspected.stream.events.some((event) => event.kind === "mission.recovered" && objectField(objectField(objectField(event.payload, "request"), "disposition"), "kind") === "review-provenance");
|
|
68578
|
-
if (hasProvenanceRecovery) for (const event of restored.events) {
|
|
68579
|
-
if (event.kind !== "specialist.completed") continue;
|
|
68580
|
-
const receipt2 = parseSpecialistCompletionValue(objectField(event.payload, "completion"))?.review;
|
|
68581
|
-
const hash7 = objectField(event.payload, "inputHash");
|
|
68582
|
-
if (receipt2 !== void 0 && sameReviewSubject(receipt2, reviewBinding2) && typeof hash7 === "string") {
|
|
68583
|
-
currentInputHashes[event.subject] = hash7;
|
|
68584
|
-
}
|
|
68585
|
-
}
|
|
68586
|
-
}
|
|
68587
68721
|
const decision = orchestrateMissionTeam({
|
|
68588
68722
|
...reviewBinding2 === void 0 ? {} : { reviewSubject: reviewBinding2 },
|
|
68589
68723
|
plan: stored.plan,
|
|
@@ -68907,7 +69041,7 @@ Fix: ${parsed.fix}
|
|
|
68907
69041
|
const journal = roots.installRoot;
|
|
68908
69042
|
try {
|
|
68909
69043
|
if (parsed.kind === "plan") {
|
|
68910
|
-
const plan2 = await planMission(root, parsed.ticketPath);
|
|
69044
|
+
const plan2 = await planMission(root, parsed.ticketPath, void 0, "project-v1");
|
|
68911
69045
|
process.stdout.write(parsed.json ? `${JSON.stringify(plan2)}
|
|
68912
69046
|
` : `${renderPlan(plan2)}
|
|
68913
69047
|
`);
|
|
@@ -68992,7 +69126,7 @@ ${dispatched.envelopes.map((envelope) => `${envelope.agentName} ${envelope.stage
|
|
|
68992
69126
|
}
|
|
68993
69127
|
if (parsed.kind === "start") {
|
|
68994
69128
|
const baseCommit = parsed.ticketPath === void 0 ? void 0 : await missionReviewBase(root);
|
|
68995
|
-
const bound = parsed.ticketPath === void 0 ? void 0 : await planBoundMission(root, parsed.ticketPath);
|
|
69129
|
+
const bound = parsed.ticketPath === void 0 ? void 0 : await planBoundMission(root, parsed.ticketPath, void 0, void 0, void 0, "project-v1");
|
|
68996
69130
|
const plan2 = bound?.plan;
|
|
68997
69131
|
const diff = plan2 === void 0 ? await gitFiles(root) : void 0;
|
|
68998
69132
|
const stack = diff === void 0 ? void 0 : detectedStack(root, detectProfileInput(root, diff.files));
|
|
@@ -69011,7 +69145,7 @@ ${dispatched.envelopes.map((envelope) => `${envelope.agentName} ${envelope.stage
|
|
|
69011
69145
|
const controllerPlan = plan2 === void 0 ? void 0 : missionSpecialistPlan(plan2);
|
|
69012
69146
|
const ticketBinding = bound?.ticket;
|
|
69013
69147
|
const runtimeIdentity = bound === void 0 ? void 0 : coordinatorRuntimeIdentity(process.env);
|
|
69014
|
-
const routingHash = controllerPlan === void 0 ? void 0 : ticketBinding === void 0 ? void 0 : missionControllerRoutingHash(controllerPlan, ticketBinding, baseCommit);
|
|
69148
|
+
const routingHash = controllerPlan === void 0 ? void 0 : ticketBinding === void 0 ? void 0 : missionControllerRoutingHash(controllerPlan, ticketBinding, baseCommit, "project-v1");
|
|
69015
69149
|
await createMission(journal, {
|
|
69016
69150
|
missionId,
|
|
69017
69151
|
title: parsed.title,
|
|
@@ -69038,7 +69172,8 @@ ${dispatched.envelopes.map((envelope) => `${envelope.agentName} ${envelope.stage
|
|
|
69038
69172
|
missionId,
|
|
69039
69173
|
controllerPlan,
|
|
69040
69174
|
ticketBinding,
|
|
69041
|
-
baseCommit
|
|
69175
|
+
baseCommit,
|
|
69176
|
+
"project-v1"
|
|
69042
69177
|
);
|
|
69043
69178
|
if (storedHash !== routingHash) {
|
|
69044
69179
|
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: routing hash changed while storing");
|