voidmachine 5.0.3 → 5.0.5
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 +212 -100
- package/package.json +3 -3
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));
|
|
@@ -35953,7 +35954,7 @@ function collectCompletions(events, stage, expectedSource, stageStartSeqExclusiv
|
|
|
35953
35954
|
}
|
|
35954
35955
|
const validAccepted = accepted.filter((envelope) => !invalidRoundEvents.has(envelope.event.eventId) && !(contractMigration !== void 0 && stage === "post-implementation" && envelope.completion.specialistId === contractMigration.specialistId && envelope.event.seq < contractMigration.afterSeq));
|
|
35955
35956
|
const highestRound = Math.max(historicalHighestRound, activeRound ?? 0);
|
|
35956
|
-
const pendingFailureRounds = [...failedRoundBySpecialist.entries()].filter(([id3]) => !
|
|
35957
|
+
const pendingFailureRounds = [...failedRoundBySpecialist.entries()].filter(([id3]) => !validAccepted.some((item) => item.completion.specialistId === id3)).map(([, round]) => round + 1);
|
|
35957
35958
|
const nextRound = Math.max(firstCurrentRound, highestRound, ...pendingFailureRounds);
|
|
35958
35959
|
return { accepted: [...retained, ...validAccepted], history, issues, highestRound, nextRound };
|
|
35959
35960
|
}
|
|
@@ -36727,7 +36728,7 @@ function staleDispatchCompletions(events) {
|
|
|
36727
36728
|
function specialistId2(value) {
|
|
36728
36729
|
return /^core:[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value);
|
|
36729
36730
|
}
|
|
36730
|
-
function validProvenanceRecovery(input2, existing) {
|
|
36731
|
+
function validProvenanceRecovery(input2, existing, afterSeqExclusive = 0) {
|
|
36731
36732
|
const disposition = input2.request.disposition;
|
|
36732
36733
|
const observation2 = input2.observation;
|
|
36733
36734
|
const bindings = observation2.reviewBindings;
|
|
@@ -36741,10 +36742,10 @@ function validProvenanceRecovery(input2, existing) {
|
|
|
36741
36742
|
const observedSubject = observation2.reviewSubject;
|
|
36742
36743
|
return bindings.every((binding3) => {
|
|
36743
36744
|
const original = existing.find((item) => item.event.eventId === binding3.completionEventId);
|
|
36744
|
-
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"))
|
|
36745
36746
|
return false;
|
|
36746
|
-
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);
|
|
36747
|
-
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)));
|
|
36748
36749
|
});
|
|
36749
36750
|
}
|
|
36750
36751
|
function pendingPreparationClarification(input2, previousRecovery) {
|
|
@@ -36777,6 +36778,55 @@ function pendingPreparationClarification(input2, previousRecovery) {
|
|
|
36777
36778
|
const completionEventIds = request.disposition.completionEventIds;
|
|
36778
36779
|
return obligations.issues.length === 0 && obligations.obligations.some((item) => blocking.has(item.obligationId) && completionEventIds.includes(item.completionEventId));
|
|
36779
36780
|
}
|
|
36781
|
+
function pendingStoppedEvidenceRequest(events, requestEventId, contextId) {
|
|
36782
|
+
const lifecycle = projectMissionLifecycle(events);
|
|
36783
|
+
if (lifecycle.status !== "closed" || lifecycle.closure.source !== "void-harness:mission.dispatch" || field4(lifecycle.closure, "reason") !== "controller-stop" || ambiguousEffects(events))
|
|
36784
|
+
return false;
|
|
36785
|
+
const request = events.find((event) => event.eventId === requestEventId);
|
|
36786
|
+
const runtime2 = events[0] === void 0 ? void 0 : field4(events[0], "runtime");
|
|
36787
|
+
if (runtime2 !== "codex" && runtime2 !== "claude" || events[0] === void 0 || field4(events[0], "runtimeAttested") !== true || !request || request.kind !== "specialist.evidence-discharge-requested" || request.source !== "void-harness:mission.dispatch" || request.seq >= lifecycle.closure.seq || field4(request, "nativeContextId") !== contextId || !validNativeContextId(contextId))
|
|
36788
|
+
return false;
|
|
36789
|
+
return events.some((event) => event.kind === "specialist.evidence-started" && event.source === `runtime:${String(runtime2)}` && event.subject === request.subject && event.causationId === request.eventId && event.seq > request.seq && event.seq < lifecycle.closure.seq && [
|
|
36790
|
+
"completionEventId",
|
|
36791
|
+
"completionHash",
|
|
36792
|
+
"specialistId",
|
|
36793
|
+
"nativeContextId",
|
|
36794
|
+
"requestId"
|
|
36795
|
+
].every((key) => field4(event, key) === field4(request, key)));
|
|
36796
|
+
}
|
|
36797
|
+
function validEvidenceDispositionRecovery(input2) {
|
|
36798
|
+
const { events } = input2.stream;
|
|
36799
|
+
const { disposition } = input2.request;
|
|
36800
|
+
if (disposition.kind !== "evidence-disposition" || disposition.responseEventIds.length < 1 || disposition.responseEventIds.length > 64 || new Set(disposition.responseEventIds).size !== disposition.responseEventIds.length)
|
|
36801
|
+
return false;
|
|
36802
|
+
const closure = events.find((event) => event.eventId === input2.request.closureEventId);
|
|
36803
|
+
if (!closure)
|
|
36804
|
+
return false;
|
|
36805
|
+
const proofs = events.flatMap((event) => {
|
|
36806
|
+
const parsed = event.kind === "evidence.recorded" ? parseEvidence(field4(event, "evidence")) : void 0;
|
|
36807
|
+
return parsed?.ok ? [{ eventId: event.eventId, evidence: parsed.value }] : [];
|
|
36808
|
+
});
|
|
36809
|
+
const reduction = {
|
|
36810
|
+
expectedSource: input2.observation.expectedSource,
|
|
36811
|
+
phase: "completion",
|
|
36812
|
+
evidenceContext: { missionId: closure.missionId, dependencies: input2.observation.evidenceDependencies ?? {} },
|
|
36813
|
+
proofs
|
|
36814
|
+
};
|
|
36815
|
+
const before = reduceEvidenceObligations({ ...reduction, events: events.filter((event) => event.seq <= closure.seq) });
|
|
36816
|
+
const after = reduceEvidenceObligations({ ...reduction, events });
|
|
36817
|
+
if (before.issues.length > 0 || after.issues.length > 0)
|
|
36818
|
+
return false;
|
|
36819
|
+
return disposition.responseEventIds.every((id3) => {
|
|
36820
|
+
const response = events.find((event) => event.eventId === id3);
|
|
36821
|
+
if (response?.kind !== "specialist.evidence-discharged" || response.seq <= closure.seq || response.source !== input2.observation.expectedSource || !response.causationId || typeof field4(response, "nativeContextId") !== "string" || !pendingStoppedEvidenceRequest(events.filter((event) => event.seq < response.seq), response.causationId, String(field4(response, "nativeContextId"))))
|
|
36822
|
+
return false;
|
|
36823
|
+
const origin = completions(events).find((item) => item.event.eventId === field4(response, "completionEventId"));
|
|
36824
|
+
if (!origin || origin.completion.contractVersion !== input2.observation.contractVersions[origin.event.subject])
|
|
36825
|
+
return false;
|
|
36826
|
+
const items = field4(response, "items");
|
|
36827
|
+
return Array.isArray(items) && items.length > 0 && items.every((item) => record10(item) && Array.isArray(item["proofEventIds"]) && item["proofEventIds"].every((id4) => proofs.some((proof4) => proof4.eventId === id4 && proof4.evidence.dependencies.some((dependency) => dependency.key === "git:working-tree" && dependency.hash === input2.observation.evidenceDependencies?.["git:working-tree"]))) && before.obligations.some((value) => value.obligationId === item["obligationId"] && !value.discharged) && after.obligations.some((value) => value.obligationId === item["obligationId"] && value.discharged));
|
|
36828
|
+
});
|
|
36829
|
+
}
|
|
36780
36830
|
function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
36781
36831
|
const { stream: stream2, request, observation: observation2 } = input2;
|
|
36782
36832
|
const events = stream2.events;
|
|
@@ -36795,11 +36845,14 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
|
36795
36845
|
return refuse2("stale-journal", "Re-observe the journal before requesting recovery");
|
|
36796
36846
|
if (ambiguousEffects(events))
|
|
36797
36847
|
return refuse2("ambiguous-effect", "Reconcile the unfinished external effect; recovery cannot replay it");
|
|
36848
|
+
if (request.disposition.kind === "evidence-disposition" && !validEvidenceDispositionRecovery(input2)) {
|
|
36849
|
+
return refuse2("invalid-evidence-disposition", "Complete a pending pre-stop author invocation with fresh canonical proofs; an old or unstarted response cannot reopen this episode");
|
|
36850
|
+
}
|
|
36851
|
+
const existing = completions(events).filter((item) => field4(item.event, "stage") === observation2.stage);
|
|
36798
36852
|
const previousRecovery = events.filter((event) => event.kind === "mission.recovered").at(-1);
|
|
36799
|
-
if (previousRecovery !== void 0 && !events.some((event) => event.seq > previousRecovery.seq && event.kind === "lead-writer.completed") && !pendingPreparationClarification(input2, previousRecovery)) {
|
|
36853
|
+
if (previousRecovery !== void 0 && !events.some((event) => event.seq > previousRecovery.seq && event.kind === "lead-writer.completed") && !pendingPreparationClarification(input2, previousRecovery) && !validEvidenceDispositionRecovery(input2) && !validProvenanceRecovery(input2, existing, previousRecovery.seq)) {
|
|
36800
36854
|
return refuse2("no-recovery-progress", "Record actual corrective progress before reopening another stopped episode");
|
|
36801
36855
|
}
|
|
36802
|
-
const existing = completions(events).filter((item) => field4(item.event, "stage") === observation2.stage);
|
|
36803
36856
|
const disposition = request.disposition;
|
|
36804
36857
|
const replacement = disposition.kind === "preparation-invocation";
|
|
36805
36858
|
if (replacement && !preparationInvocationReplacement(input2)) {
|
|
@@ -36879,7 +36932,7 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
|
36879
36932
|
requiredSpecialists: required2,
|
|
36880
36933
|
contractVersions: observation2.contractVersions,
|
|
36881
36934
|
currentInputHashes: observation2.currentInputHashes,
|
|
36882
|
-
maxRounds: observation2.maxRounds
|
|
36935
|
+
...observation2.reviewPolicy === "bounded-corrections-v1" ? BOUNDED_REVIEW_BUDGET : { maxRounds: observation2.maxRounds }
|
|
36883
36936
|
};
|
|
36884
36937
|
const originalReview = reduceReviewLoop({ ...reviewInput, events: projectedHistory });
|
|
36885
36938
|
if (originalReview.issues.some((issue4) => replacement ? issue4.code !== "reused-context" || !inadmissible.includes(issue4.eventId) : issue4.code !== "wrong-review-round")) {
|
|
@@ -36893,7 +36946,7 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
|
36893
36946
|
return refuse2("incomplete-required-panel", "Every required preparation specialist must have its original matching PASS triplet before recovery");
|
|
36894
36947
|
}
|
|
36895
36948
|
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"))));
|
|
36896
|
-
if (!replacement && disposition.kind !== "review-provenance" && consumedRounds >=
|
|
36949
|
+
if (!replacement && disposition.kind !== "review-provenance" && consumedRounds >= reviewInput.maxRounds)
|
|
36897
36950
|
return refuse2("review-budget-exhausted", "The real review budget is exhausted; recovery cannot reset it");
|
|
36898
36951
|
const consumedCorrectionBatches = projected.filter((event) => event.kind === "lead-writer.completed" && field4(event, "actionKind") === "run-correction").length;
|
|
36899
36952
|
if (disposition.kind === "review-provenance" && consumedCorrectionBatches > 2) {
|
|
@@ -36915,12 +36968,12 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
|
|
|
36915
36968
|
inadmissibleCompletionEventIds: inadmissible,
|
|
36916
36969
|
roundCorrections,
|
|
36917
36970
|
consumedRounds,
|
|
36918
|
-
remainingRounds: Math.max(0,
|
|
36971
|
+
remainingRounds: Math.max(0, reviewInput.maxRounds - consumedRounds),
|
|
36919
36972
|
...!replacement && disposition.kind !== "review-provenance" ? {} : {
|
|
36920
36973
|
consumedCorrectionBatches,
|
|
36921
36974
|
remainingCorrectionBatches: 2 - consumedCorrectionBatches
|
|
36922
36975
|
},
|
|
36923
|
-
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"
|
|
36976
|
+
nextAction: replacement || disposition.kind === "evidence-disposition" || 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
36977
|
};
|
|
36925
36978
|
if (new TextEncoder().encode(canonicalJson(receipt2)).length > 16384) {
|
|
36926
36979
|
return refuse2("recovery-receipt-too-large", "Narrow the recovery scope to the supported bounded incident");
|
|
@@ -36937,6 +36990,10 @@ function recoveryRequest(value) {
|
|
|
36937
36990
|
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"]))
|
|
36938
36991
|
return false;
|
|
36939
36992
|
const disposition = value["disposition"];
|
|
36993
|
+
if (disposition["kind"] === "evidence-disposition") {
|
|
36994
|
+
const ids = disposition["responseEventIds"];
|
|
36995
|
+
return exactKeys2(disposition, ["kind", "responseEventIds"]) && Array.isArray(ids) && ids.length > 0 && ids.length <= 64 && new Set(ids).size === ids.length && ids.every((id3) => typeof id3 === "string" && /^evt_[A-Za-z0-9_-]{8,100}$/.test(id3));
|
|
36996
|
+
}
|
|
36940
36997
|
if (disposition["kind"] === "preparation-invocation") {
|
|
36941
36998
|
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;
|
|
36942
36999
|
}
|
|
@@ -36960,11 +37017,12 @@ function recoveryObservation(value) {
|
|
|
36960
37017
|
"currentInputHashes",
|
|
36961
37018
|
"maxRounds",
|
|
36962
37019
|
"expectedSource",
|
|
37020
|
+
...value["reviewPolicy"] === void 0 ? [] : ["reviewPolicy"],
|
|
36963
37021
|
...value["resolutionArtifact"] === void 0 ? [] : ["resolutionArtifact"],
|
|
36964
37022
|
...value["reviewSubject"] === void 0 ? [] : ["reviewSubject"],
|
|
36965
37023
|
...value["reviewBindings"] === void 0 ? [] : ["reviewBindings"],
|
|
36966
37024
|
...value["evidenceDependencies"] === void 0 ? [] : ["evidenceDependencies"]
|
|
36967
|
-
]) || !["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"]))
|
|
37025
|
+
]) || 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"]))
|
|
36968
37026
|
return false;
|
|
36969
37027
|
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)));
|
|
36970
37028
|
}
|
|
@@ -38880,7 +38938,7 @@ function evidenceObligations(input2, expectedSource, phase) {
|
|
|
38880
38938
|
evidenceContext: input2.evidenceContext
|
|
38881
38939
|
});
|
|
38882
38940
|
}
|
|
38883
|
-
function obligationStop(state, review, verdict
|
|
38941
|
+
function obligationStop(state, review, verdict) {
|
|
38884
38942
|
if (state.issues.length > 0) {
|
|
38885
38943
|
return stopped("degraded", review, verdict, state.issues.map((issue4) => `Evidence obligation ${issue4.eventId}: ${issue4.detail}`), "Resolve the invalid specialist evidence disposition, then classify or discharge the original obligation through its authorized specialist.");
|
|
38886
38944
|
}
|
|
@@ -38888,7 +38946,7 @@ function obligationStop(state, review, verdict, preparation = false) {
|
|
|
38888
38946
|
if (blocking.size === 0)
|
|
38889
38947
|
return void 0;
|
|
38890
38948
|
const decision = stopped("blocked", review, verdict, state.obligations.filter((item) => blocking.has(item.obligationId)).map((item) => `Evidence obligation ${item.obligationId} (${item.due}): ${item.requestText}`), "Use mission evidence-request, then record the authorized author response with mission evidence-event to classify or discharge the obligation; a writer completion does not replace the required proof.");
|
|
38891
|
-
return
|
|
38949
|
+
return { ...decision, action: { kind: "await-evidence", reasons: decision.reasons } };
|
|
38892
38950
|
}
|
|
38893
38951
|
function orchestrateMissionTeam(originalInput) {
|
|
38894
38952
|
const migrated = validatedSpecialistContractMigrations(originalInput.stream.events, originalInput.plan);
|
|
@@ -38984,7 +39042,10 @@ function orchestrateMissionTeam(originalInput) {
|
|
|
38984
39042
|
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])) {
|
|
38985
39043
|
return stopped("blocked", preReview, baseVerdict, ["Preparation replacement inputs or contracts changed; reconcile the admitted subject before dispatch"]);
|
|
38986
39044
|
}
|
|
38987
|
-
|
|
39045
|
+
if (firstImplementationSeq !== void 0 && input2.stream.events.some((event) => event.kind === "specialist.completed" && event.seq > firstImplementationSeq && lifecycleField(event, "stage") === "pre-implementation")) {
|
|
39046
|
+
return stopped("blocked", preReview, baseVerdict, ["pre-implementation review was replayed after implementation"]);
|
|
39047
|
+
}
|
|
39048
|
+
const pendingEvidence = obligationStop(obligations, preReview, baseVerdict);
|
|
38988
39049
|
const migration = migrated.migration;
|
|
38989
39050
|
if (migration !== void 0) {
|
|
38990
39051
|
const receipt2 = migration.receipt;
|
|
@@ -39010,6 +39071,33 @@ function orchestrateMissionTeam(originalInput) {
|
|
|
39010
39071
|
}, input2.specialistRuntime);
|
|
39011
39072
|
}
|
|
39012
39073
|
}
|
|
39074
|
+
const postReview = firstImplementationSeq === void 0 || lastWriterSeq === void 0 ? void 0 : reduceReviewLoop({
|
|
39075
|
+
stage: "post-implementation",
|
|
39076
|
+
expectedSource,
|
|
39077
|
+
stageStartSeqExclusive: firstImplementationSeq,
|
|
39078
|
+
afterSeqExclusive: lastWriterSeq,
|
|
39079
|
+
events: reviewEvents,
|
|
39080
|
+
requiredSpecialists: requiredSpecialists(input2.plan, "post-implementation", start.boundedReview),
|
|
39081
|
+
contractVersions: contractVersions(input2.plan),
|
|
39082
|
+
currentInputHashes: input2.currentInputHashesByStage["post-implementation"],
|
|
39083
|
+
...start.boundedReview ? BOUNDED_REVIEW_BUDGET : { maxRounds: input2.maxReviewRounds },
|
|
39084
|
+
// Pending proofs are handled by obligationStop; they must not mask failed reviews.
|
|
39085
|
+
evidenceObligations: { ...obligations, blockingObligationIds: [] },
|
|
39086
|
+
validProofIds: input2.stream.events.flatMap((event) => {
|
|
39087
|
+
if (event.kind !== "evidence.recorded")
|
|
39088
|
+
return [];
|
|
39089
|
+
const parsed = parseEvidence(lifecycleField(event, "evidence"));
|
|
39090
|
+
return parsed.ok && parsed.value.evidenceId === event.subject && parsed.value.missionId === event.missionId && parsed.value.status === "passed" && assessEvidence(parsed.value, input2.evidenceContext).status === "fresh" ? [parsed.value.evidenceId] : [];
|
|
39091
|
+
}),
|
|
39092
|
+
...migration === void 0 ? {} : { contractMigration: {
|
|
39093
|
+
specialistId: migration.receipt.specialistId,
|
|
39094
|
+
afterSeq: migration.seq,
|
|
39095
|
+
reviewRound: migration.receipt.reviewRound
|
|
39096
|
+
} }
|
|
39097
|
+
});
|
|
39098
|
+
if (postReview?.status === "blocked" || postReview?.status === "degraded") {
|
|
39099
|
+
return applyRuntimeCertification(decideReviewPhase(start, postReview, baseVerdict, "post-implementation"), input2.specialistRuntime);
|
|
39100
|
+
}
|
|
39013
39101
|
const correctiveFindingIds = pendingRecoveredCorrectionFindingIds(input2.stream.events);
|
|
39014
39102
|
const correctiveContinuation = pendingEvidence !== void 0 && obligations.issues.length === 0 && firstImplementationSeq !== void 0 && correctiveFindingIds.length > 0;
|
|
39015
39103
|
if (pendingEvidence !== void 0 && !correctiveContinuation) {
|
|
@@ -39058,33 +39146,9 @@ function orchestrateMissionTeam(originalInput) {
|
|
|
39058
39146
|
reasons
|
|
39059
39147
|
}, input2.specialistRuntime);
|
|
39060
39148
|
}
|
|
39061
|
-
if (firstWriterSeq === void 0 || firstImplementationSeq === void 0 || lastWriterSeq === void 0) {
|
|
39149
|
+
if (firstWriterSeq === void 0 || firstImplementationSeq === void 0 || lastWriterSeq === void 0 || postReview === void 0) {
|
|
39062
39150
|
throw new Error("MISSION_TEAM_INVARIANT: writer completion boundary is missing");
|
|
39063
39151
|
}
|
|
39064
|
-
const postReview = reduceReviewLoop({
|
|
39065
|
-
stage: "post-implementation",
|
|
39066
|
-
expectedSource,
|
|
39067
|
-
stageStartSeqExclusive: firstImplementationSeq,
|
|
39068
|
-
afterSeqExclusive: lastWriterSeq,
|
|
39069
|
-
events: reviewEvents,
|
|
39070
|
-
requiredSpecialists: requiredSpecialists(input2.plan, "post-implementation", start.boundedReview),
|
|
39071
|
-
contractVersions: contractVersions(input2.plan),
|
|
39072
|
-
currentInputHashes: input2.currentInputHashesByStage["post-implementation"],
|
|
39073
|
-
maxRounds: start.boundedReview ? 3 : input2.maxReviewRounds,
|
|
39074
|
-
...start.boundedReview ? { maxCorrectionBatches: 2 } : {},
|
|
39075
|
-
evidenceObligations: obligations,
|
|
39076
|
-
validProofIds: input2.stream.events.flatMap((event) => {
|
|
39077
|
-
if (event.kind !== "evidence.recorded")
|
|
39078
|
-
return [];
|
|
39079
|
-
const parsed = parseEvidence(lifecycleField(event, "evidence"));
|
|
39080
|
-
return parsed.ok && parsed.value.evidenceId === event.subject && parsed.value.missionId === event.missionId && parsed.value.status === "passed" && assessEvidence(parsed.value, input2.evidenceContext).status === "fresh" ? [parsed.value.evidenceId] : [];
|
|
39081
|
-
}),
|
|
39082
|
-
...migration === void 0 ? {} : { contractMigration: {
|
|
39083
|
-
specialistId: migration.receipt.specialistId,
|
|
39084
|
-
afterSeq: migration.seq,
|
|
39085
|
-
reviewRound: migration.receipt.reviewRound
|
|
39086
|
-
} }
|
|
39087
|
-
});
|
|
39088
39152
|
if (start.boundedReview && postReview.missingSpecialists.length === 0) {
|
|
39089
39153
|
const receiptReasons = boundedReceiptReasons(input2, start, reviewEvents);
|
|
39090
39154
|
if (receiptReasons.length > 0)
|
|
@@ -46578,7 +46642,7 @@ function dependencyEntries(pkg) {
|
|
|
46578
46642
|
function technology(id3, version3, source2) {
|
|
46579
46643
|
return Object.freeze({ id: id3, version: version3, sources: Object.freeze([source2]) });
|
|
46580
46644
|
}
|
|
46581
|
-
function packageTechnologies(workspace) {
|
|
46645
|
+
function packageTechnologies(workspace, recipe) {
|
|
46582
46646
|
const technologies = /* @__PURE__ */ new Map();
|
|
46583
46647
|
const source2 = workspace.path === "." ? "package.json" : `${workspace.path}/package.json`;
|
|
46584
46648
|
for (const [dependency, version3] of dependencyEntries(workspace.packageJson)) {
|
|
@@ -46591,7 +46655,10 @@ function packageTechnologies(workspace) {
|
|
|
46591
46655
|
}
|
|
46592
46656
|
}
|
|
46593
46657
|
if (workspace.path === ".") {
|
|
46594
|
-
|
|
46658
|
+
const declaredNode2 = workspace.packageJson.engines?.node;
|
|
46659
|
+
const projectNode = typeof declaredNode2 === "string" && /^\d+\.\d+\.\d+$/.test(declaredNode2) ? declaredNode2 : null;
|
|
46660
|
+
const projectNodeSource = projectNode === null && typeof declaredNode2 === "string" ? `package.json:engines.node:${declaredNode2}` : "package.json:engines.node";
|
|
46661
|
+
technologies.set("node", recipe === "runtime-v1" ? technology("node", exactVersion(process.versions.node), "runtime:node") : technology("node", projectNode, projectNodeSource));
|
|
46595
46662
|
const packageManager = workspace.packageJson.packageManager;
|
|
46596
46663
|
if (packageManager !== void 0) {
|
|
46597
46664
|
const separator = packageManager.indexOf("@");
|
|
@@ -46617,7 +46684,7 @@ function packageTechnologies(workspace) {
|
|
|
46617
46684
|
function validChangedFile(file2) {
|
|
46618
46685
|
return file2.length > 0 && !file2.startsWith("/") && !file2.startsWith("../") && !file2.includes("/../") && !file2.includes("\\") && posix.normalize(file2) === file2;
|
|
46619
46686
|
}
|
|
46620
|
-
function detectProfileInput(root, files) {
|
|
46687
|
+
function detectProfileInput(root, files, recipe = "runtime-v1") {
|
|
46621
46688
|
if (!files.every(validChangedFile)) {
|
|
46622
46689
|
throw new Error("PROFILE_INPUT_INVALID: changed files must remain inside the project root");
|
|
46623
46690
|
}
|
|
@@ -46625,7 +46692,7 @@ function detectProfileInput(root, files) {
|
|
|
46625
46692
|
const rootWorkspace = workspaces.find((workspace) => workspace.path === ".");
|
|
46626
46693
|
const projects2 = workspaces.map((workspace) => Object.freeze({
|
|
46627
46694
|
path: workspace.path,
|
|
46628
|
-
technologies: packageTechnologies(workspace)
|
|
46695
|
+
technologies: packageTechnologies(workspace, recipe)
|
|
46629
46696
|
}));
|
|
46630
46697
|
if (projects2.length > 1) {
|
|
46631
46698
|
const rootProject = projects2.find((project) => project.path === ".");
|
|
@@ -55863,17 +55930,18 @@ async function createMission(root, input2) {
|
|
|
55863
55930
|
);
|
|
55864
55931
|
await writeMissionMetadata(run2, safeInput, createdAt);
|
|
55865
55932
|
}
|
|
55866
|
-
async function writeMissionControllerPlan(root, missionId, plan2, ticket, baseCommit) {
|
|
55933
|
+
async function writeMissionControllerPlan(root, missionId, plan2, ticket, baseCommit, inputRecipe) {
|
|
55867
55934
|
const run2 = await existingRunDirectory(root, missionId);
|
|
55868
|
-
const routingHash = missionControllerRoutingHash(plan2, ticket, baseCommit);
|
|
55935
|
+
const routingHash = missionControllerRoutingHash(plan2, ticket, baseCommit, inputRecipe);
|
|
55869
55936
|
const handle3 = await open$1(join(run2, "controller-plan.json"), "wx", 384);
|
|
55870
55937
|
try {
|
|
55871
55938
|
await handle3.writeFile(`${JSON.stringify({
|
|
55872
|
-
schemaVersion: baseCommit === void 0 ? 1 : 2,
|
|
55939
|
+
schemaVersion: inputRecipe === void 0 ? baseCommit === void 0 ? 1 : 2 : 3,
|
|
55873
55940
|
routingHash,
|
|
55874
55941
|
plan: plan2,
|
|
55875
55942
|
ticket,
|
|
55876
|
-
...baseCommit === void 0 ? {} : { baseCommit }
|
|
55943
|
+
...baseCommit === void 0 ? {} : { baseCommit },
|
|
55944
|
+
...inputRecipe === void 0 ? {} : { inputRecipe }
|
|
55877
55945
|
})}
|
|
55878
55946
|
`, "utf8");
|
|
55879
55947
|
} finally {
|
|
@@ -55902,28 +55970,38 @@ async function loadMissionControllerPlan(root, missionId) {
|
|
|
55902
55970
|
"routingHash",
|
|
55903
55971
|
"plan",
|
|
55904
55972
|
"ticket",
|
|
55905
|
-
...parsed.schemaVersion === 2 ? ["baseCommit"] : []
|
|
55973
|
+
...parsed.schemaVersion === 2 || parsed.schemaVersion === 3 ? ["baseCommit"] : [],
|
|
55974
|
+
...parsed.schemaVersion === 3 ? ["inputRecipe"] : []
|
|
55906
55975
|
])) {
|
|
55907
55976
|
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: plan envelope is malformed");
|
|
55908
55977
|
}
|
|
55909
55978
|
const plan2 = parseMissionSpecialistPlan(parsed.plan);
|
|
55910
55979
|
const ticket = parseMissionControllerTicket(parsed.ticket);
|
|
55911
55980
|
const routingHash = typeof parsed.routingHash === "string" ? parsed.routingHash : "";
|
|
55912
|
-
const baseCommit = parsed.schemaVersion === 2 ? parsed.baseCommit : void 0;
|
|
55913
|
-
|
|
55981
|
+
const baseCommit = parsed.schemaVersion === 2 || parsed.schemaVersion === 3 ? parsed.baseCommit : void 0;
|
|
55982
|
+
const inputRecipe = parsed.schemaVersion === 3 && parsed.inputRecipe === "project-v1" ? "project-v1" : void 0;
|
|
55983
|
+
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)) {
|
|
55914
55984
|
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: plan integrity check failed");
|
|
55915
55985
|
}
|
|
55916
55986
|
const base = typeof baseCommit === "string" ? { baseCommit } : {};
|
|
55917
|
-
if (missionControllerRoutingHash(plan2, ticket, base.baseCommit) !== routingHash) {
|
|
55987
|
+
if (missionControllerRoutingHash(plan2, ticket, base.baseCommit, inputRecipe) !== routingHash) {
|
|
55918
55988
|
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: plan integrity check failed");
|
|
55919
55989
|
}
|
|
55920
|
-
return Object.freeze({ plan: plan2, ticket, routingHash, ...base });
|
|
55990
|
+
return Object.freeze({ plan: plan2, ticket, routingHash, ...base, ...inputRecipe === void 0 ? {} : { inputRecipe } });
|
|
55921
55991
|
}
|
|
55922
|
-
function missionControllerRoutingHash(plan2, ticket, baseCommit) {
|
|
55992
|
+
function missionControllerRoutingHash(plan2, ticket, baseCommit, inputRecipe) {
|
|
55993
|
+
if (inputRecipe !== void 0 && (inputRecipe !== "project-v1" || baseCommit === void 0)) {
|
|
55994
|
+
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: project input recipe requires a committed baseline");
|
|
55995
|
+
}
|
|
55923
55996
|
if (baseCommit !== void 0 && !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(baseCommit)) {
|
|
55924
55997
|
throw new Error("MISSION_REVIEW_BASE_INVALID: expected a full commit object ID");
|
|
55925
55998
|
}
|
|
55926
|
-
return canonicalJsonHash({
|
|
55999
|
+
return canonicalJsonHash({
|
|
56000
|
+
plan: plan2,
|
|
56001
|
+
ticket,
|
|
56002
|
+
...baseCommit === void 0 ? {} : { baseCommit },
|
|
56003
|
+
...inputRecipe === void 0 ? {} : { inputRecipe }
|
|
56004
|
+
});
|
|
55927
56005
|
}
|
|
55928
56006
|
function unknownRecord2(value) {
|
|
55929
56007
|
return typeof value === "object" && Boolean(value) && !Array.isArray(value);
|
|
@@ -56335,6 +56413,7 @@ async function loadProfiles(root, coreProfileDirectory) {
|
|
|
56335
56413
|
// src/lib/mission-inputs.ts
|
|
56336
56414
|
var execFile2 = promisify(execFile);
|
|
56337
56415
|
var MAX_TICKET_BYTES = 1e5;
|
|
56416
|
+
var MAX_REVIEW_PATCH_BYTES = 16e6;
|
|
56338
56417
|
async function readTicket(root, ticketPath) {
|
|
56339
56418
|
const canonicalRoot = await realpath(resolve(root));
|
|
56340
56419
|
const loaded = await readBoundedProjectFile({
|
|
@@ -56390,7 +56469,7 @@ async function missionReviewBase(root) {
|
|
|
56390
56469
|
throw new Error("MISSION_REVIEW_BASE_INVALID: a committed Git baseline is required");
|
|
56391
56470
|
}
|
|
56392
56471
|
}
|
|
56393
|
-
async function captureMissionReviewSubject(root, baseCommit, committed = false) {
|
|
56472
|
+
async function captureMissionReviewSubject(root, baseCommit, committed = false, hashFormat = committed ? "committed" : "legacy") {
|
|
56394
56473
|
if (baseCommit === void 0) {
|
|
56395
56474
|
throw new Error(
|
|
56396
56475
|
"MISSION_REVIEW_BASE_MISSING: legacy mission has no review baseline; preserve its history and start a new mission"
|
|
@@ -56430,7 +56509,17 @@ async function captureMissionReviewSubject(root, baseCommit, committed = false)
|
|
|
56430
56509
|
"--relative",
|
|
56431
56510
|
...range,
|
|
56432
56511
|
...paths
|
|
56433
|
-
],
|
|
56512
|
+
], {
|
|
56513
|
+
...options2,
|
|
56514
|
+
maxBuffer: MAX_REVIEW_PATCH_BYTES
|
|
56515
|
+
}).catch((error62) => {
|
|
56516
|
+
if (error62 instanceof Error && "code" in error62 && error62.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") {
|
|
56517
|
+
throw new Error(
|
|
56518
|
+
`MISSION_REVIEW_PATCH_TOO_LARGE: Git review patch exceeds ${MAX_REVIEW_PATCH_BYTES} bytes`
|
|
56519
|
+
);
|
|
56520
|
+
}
|
|
56521
|
+
throw error62;
|
|
56522
|
+
}),
|
|
56434
56523
|
execFile2("git", [
|
|
56435
56524
|
"diff",
|
|
56436
56525
|
"--no-ext-diff",
|
|
@@ -56463,7 +56552,7 @@ async function captureMissionReviewSubject(root, baseCommit, committed = false)
|
|
|
56463
56552
|
files,
|
|
56464
56553
|
hash: canonicalJsonHash({
|
|
56465
56554
|
baseCommit,
|
|
56466
|
-
...
|
|
56555
|
+
...hashFormat === "legacy" ? {} : { reviewedCommit },
|
|
56467
56556
|
diff: patch.stdout,
|
|
56468
56557
|
files: files.files
|
|
56469
56558
|
})
|
|
@@ -56537,10 +56626,10 @@ function detectedStack(root, profileInput) {
|
|
|
56537
56626
|
status: "known"
|
|
56538
56627
|
});
|
|
56539
56628
|
}
|
|
56540
|
-
async function planMission(root, ticketPath, generatedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
56541
|
-
return (await planBoundMission(root, ticketPath, generatedAt)).plan;
|
|
56629
|
+
async function planMission(root, ticketPath, generatedAt = (/* @__PURE__ */ new Date()).toISOString(), inputRecipe = "runtime-v1") {
|
|
56630
|
+
return (await planBoundMission(root, ticketPath, generatedAt, void 0, void 0, inputRecipe)).plan;
|
|
56542
56631
|
}
|
|
56543
|
-
async function compileMission(root, ticket, generatedAt, detectedFiles, specialistCatalog) {
|
|
56632
|
+
async function compileMission(root, ticket, generatedAt, detectedFiles, specialistCatalog, inputRecipe = "runtime-v1") {
|
|
56544
56633
|
const [coreRoot, diff] = await Promise.all([
|
|
56545
56634
|
findCoreSource(),
|
|
56546
56635
|
detectedFiles ?? gitFiles(root)
|
|
@@ -56550,7 +56639,7 @@ async function compileMission(root, ticket, generatedAt, detectedFiles, speciali
|
|
|
56550
56639
|
loadProfiles(root, join(coreRoot, "profiles")),
|
|
56551
56640
|
specialistCatalog ?? loadSpecialists(coreRoot)
|
|
56552
56641
|
]);
|
|
56553
|
-
const profileInput = detectProfileInput(root, diff.files);
|
|
56642
|
+
const profileInput = detectProfileInput(root, diff.files, inputRecipe);
|
|
56554
56643
|
const stack = detectedStack(root, profileInput);
|
|
56555
56644
|
return compileMissionPlan({
|
|
56556
56645
|
ticket: { id: ticket.id, title: ticket.title, body: ticket.body },
|
|
@@ -56570,9 +56659,9 @@ function controllerTicketBinding(ticket) {
|
|
|
56570
56659
|
contentHash: `sha256:${createHash("sha256").update(ticket.body).digest("hex")}`
|
|
56571
56660
|
});
|
|
56572
56661
|
}
|
|
56573
|
-
async function planBoundMission(root, ticketPath, generatedAt = (/* @__PURE__ */ new Date()).toISOString(), detectedFiles, specialistCatalog) {
|
|
56662
|
+
async function planBoundMission(root, ticketPath, generatedAt = (/* @__PURE__ */ new Date()).toISOString(), detectedFiles, specialistCatalog, inputRecipe = "runtime-v1") {
|
|
56574
56663
|
const ticket = await readTicket(root, ticketPath);
|
|
56575
|
-
const plan2 = await compileMission(root, ticket, generatedAt, detectedFiles, specialistCatalog);
|
|
56664
|
+
const plan2 = await compileMission(root, ticket, generatedAt, detectedFiles, specialistCatalog, inputRecipe);
|
|
56576
56665
|
return Object.freeze({
|
|
56577
56666
|
plan: plan2,
|
|
56578
56667
|
ticket: controllerTicketBinding(ticket)
|
|
@@ -67137,6 +67226,11 @@ function parseMissionRecoveryRequest(value) {
|
|
|
67137
67226
|
if (!exact2(disposition, ["kind", "defect"]) || defect !== "partial-fanout-round" && defect !== "stale-input-dispatch" && defect !== "opaque-native-context") invalid11();
|
|
67138
67227
|
return { ...base, disposition: { kind: "controller-defect", defect } };
|
|
67139
67228
|
}
|
|
67229
|
+
if (disposition["kind"] === "evidence-disposition") {
|
|
67230
|
+
const ids2 = disposition["responseEventIds"];
|
|
67231
|
+
if (!exact2(disposition, ["kind", "responseEventIds"]) || !Array.isArray(ids2) || ids2.length < 1 || ids2.length > 64 || !ids2.every(eventId) || new Set(ids2).size !== ids2.length) invalid11();
|
|
67232
|
+
return { ...base, disposition: { kind: "evidence-disposition", responseEventIds: ids2 } };
|
|
67233
|
+
}
|
|
67140
67234
|
const commandCorrection = disposition["kind"] === "command-correction";
|
|
67141
67235
|
const ids = disposition["completionEventIds"];
|
|
67142
67236
|
if (disposition["kind"] === "preparation-invocation") {
|
|
@@ -67418,13 +67512,22 @@ async function validateCompletion(events, candidate, roots, expectedSource) {
|
|
|
67418
67512
|
if (discharge2) {
|
|
67419
67513
|
const items = field7(candidate.payload, "items");
|
|
67420
67514
|
if (!Array.isArray(items) || items.some((item) => !record25(item) || !state.obligations.some((value) => value.obligationId === item["obligationId"] && value.discharged))) {
|
|
67421
|
-
invalid13(
|
|
67515
|
+
invalid13(`requested obligations need fresh successful canonical proofs; observed git:working-tree ${dependencies["git:working-tree"]} at ${roots.workRoot}; run from the proof worktree and inspect its commit/diff binding`);
|
|
67422
67516
|
}
|
|
67423
67517
|
}
|
|
67424
67518
|
}
|
|
67425
|
-
|
|
67426
|
-
|
|
67519
|
+
function requireResponseAdmission(events, status3, input2) {
|
|
67520
|
+
if (observedMissionLifecycle(events).status === "open") return;
|
|
67521
|
+
if (status3 === "completed" && pendingStoppedEvidenceRequest(events, input2.requestEventId, input2.contextId)) return;
|
|
67427
67522
|
requireOpenMission(events);
|
|
67523
|
+
}
|
|
67524
|
+
async function recordSpecialistEvidence(roots, missionId, status3, input2) {
|
|
67525
|
+
const { stream: stream2 } = await inspectMission(roots.installRoot, missionId, { dependencies: {} });
|
|
67526
|
+
if (stream2.continuity !== "complete" || stream2.invalidLines > 0 || stream2.duplicateEventIds > 0) {
|
|
67527
|
+
invalid13("complete unaltered journal is required before author response admission");
|
|
67528
|
+
}
|
|
67529
|
+
const events = stream2.events;
|
|
67530
|
+
requireResponseAdmission(events, status3, input2);
|
|
67428
67531
|
const source2 = identity(events);
|
|
67429
67532
|
const request = exactRequest(events, input2);
|
|
67430
67533
|
const kind2 = status3 === "started" ? "specialist.evidence-started" : request.kind === "specialist.evidence-classification-requested" ? "specialist.evidence-classified" : "specialist.evidence-discharged";
|
|
@@ -67448,7 +67551,7 @@ async function recordSpecialistEvidence(roots, missionId, status3, input2) {
|
|
|
67448
67551
|
eventId: id3,
|
|
67449
67552
|
draft,
|
|
67450
67553
|
validate: async (current) => {
|
|
67451
|
-
|
|
67554
|
+
requireResponseAdmission(current, status3, input2);
|
|
67452
67555
|
exactRequest(current, input2);
|
|
67453
67556
|
if (status3 === "completed") {
|
|
67454
67557
|
const started = current.find((event) => event.kind === "specialist.evidence-started" && event.source === source2 && event.subject === request.subject && event.causationId === request.eventId && field7(event.payload, "nativeContextId") === input2.contextId);
|
|
@@ -67489,6 +67592,9 @@ function parseSpecialistEvidenceRequest(value) {
|
|
|
67489
67592
|
return { ...base, operation: "discharge", obligationIds: ids };
|
|
67490
67593
|
}
|
|
67491
67594
|
function responseItem(value) {
|
|
67595
|
+
if (record25(value) && typeof value["reason"] === "string" && value["reason"].length > 1e3) {
|
|
67596
|
+
invalid13(`reason has ${value["reason"].length} characters; maximum is 1000; request a corrected author response`);
|
|
67597
|
+
}
|
|
67492
67598
|
if (!record25(value) || !text5(value["reason"])) invalid13("an author reason is required for each disposition");
|
|
67493
67599
|
if ("requestIndex" in value) {
|
|
67494
67600
|
const due2 = value["due"];
|
|
@@ -67920,7 +68026,7 @@ async function recordSpecialistRequests(root, missionId, envelopes, planHash) {
|
|
|
67920
68026
|
init_esm_shims();
|
|
67921
68027
|
|
|
67922
68028
|
// package.json
|
|
67923
|
-
var version2 = "5.0.
|
|
68029
|
+
var version2 = "5.0.5";
|
|
67924
68030
|
|
|
67925
68031
|
// src/lib/runs/verify.ts
|
|
67926
68032
|
var MAX_CAPTURE_BYTES = 64 * 1024;
|
|
@@ -68430,8 +68536,8 @@ async function migrateMissionSpecialist(roots, missionId, request) {
|
|
|
68430
68536
|
throw new Error(`SPECIALIST_CONTRACT_MIGRATION_NATIVE: ${capability.limitations.join("; ")}`);
|
|
68431
68537
|
}
|
|
68432
68538
|
const assets = await observeSpecialistMigrationAssets(coreRoot, installRoot, identity2.runtime);
|
|
68433
|
-
const subject = await
|
|
68434
|
-
const live = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files);
|
|
68539
|
+
const subject = await captureControllerReviewSubject(workRoot, stored.baseCommit, current.inspected.stream.events);
|
|
68540
|
+
const live = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, void 0, stored.inputRecipe);
|
|
68435
68541
|
if (live.ticket.path !== stored.ticket.path || live.ticket.contentHash !== stored.ticket.contentHash) {
|
|
68436
68542
|
throw new Error("MISSION_TICKET_CHANGED: migration cannot replace the bound ticket");
|
|
68437
68543
|
}
|
|
@@ -68440,7 +68546,7 @@ async function migrateMissionSpecialist(roots, missionId, request) {
|
|
|
68440
68546
|
canonicalJsonHash({ routing: specialist.proof.inputHash, subject: subject.hash })
|
|
68441
68547
|
]));
|
|
68442
68548
|
const comparisonCatalog = await loadSpecialistMigrationComparisonCatalog(coreRoot, assets.declaration, stored.plan);
|
|
68443
|
-
const comparison = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, comparisonCatalog);
|
|
68549
|
+
const comparison = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, comparisonCatalog, stored.inputRecipe);
|
|
68444
68550
|
const originalHashes = Object.fromEntries(comparison.plan.specialists.map((specialist) => [
|
|
68445
68551
|
specialist.specialistId,
|
|
68446
68552
|
canonicalJsonHash({ routing: specialist.proof.inputHash, subject: subject.hash })
|
|
@@ -68465,6 +68571,18 @@ async function migrateMissionSpecialist(roots, missionId, request) {
|
|
|
68465
68571
|
nativeAgentSha256: assets.nativeAgentSha256
|
|
68466
68572
|
} };
|
|
68467
68573
|
}
|
|
68574
|
+
function boundedMissionReview(events) {
|
|
68575
|
+
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");
|
|
68576
|
+
}
|
|
68577
|
+
function captureControllerReviewSubject(root, baseCommit, events, requireCommitted = false) {
|
|
68578
|
+
const committedFormat = events.some((event) => event.kind === "mission.started" && objectField(event.payload, "reviewPolicy") === "bounded-corrections-v1");
|
|
68579
|
+
return captureMissionReviewSubject(
|
|
68580
|
+
root,
|
|
68581
|
+
baseCommit,
|
|
68582
|
+
requireCommitted || boundedMissionReview(events),
|
|
68583
|
+
committedFormat ? "committed" : "legacy"
|
|
68584
|
+
);
|
|
68585
|
+
}
|
|
68468
68586
|
async function recoverStoppedMission(roots, missionId, request) {
|
|
68469
68587
|
const { workRoot, installRoot } = roots;
|
|
68470
68588
|
const [stored, current, coreRoot] = await Promise.all([
|
|
@@ -68496,8 +68614,13 @@ async function recoverStoppedMission(roots, missionId, request) {
|
|
|
68496
68614
|
}
|
|
68497
68615
|
}
|
|
68498
68616
|
const implemented = inspected.stream.events.some((event) => event.kind === "lead-writer.completed" && objectField(event.payload, "actionKind") !== "run-preparation-correction");
|
|
68499
|
-
const subject = implemented ? await
|
|
68500
|
-
|
|
68617
|
+
const subject = implemented ? await captureControllerReviewSubject(
|
|
68618
|
+
workRoot,
|
|
68619
|
+
stored.baseCommit,
|
|
68620
|
+
inspected.stream.events,
|
|
68621
|
+
provenanceRecovery
|
|
68622
|
+
) : void 0;
|
|
68623
|
+
const live = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject?.files, void 0, stored.inputRecipe);
|
|
68501
68624
|
if (live.ticket.path !== stored.ticket.path || live.ticket.contentHash !== stored.ticket.contentHash) {
|
|
68502
68625
|
throw new Error("MISSION_TICKET_CHANGED: recovery cannot replace the original ticket");
|
|
68503
68626
|
}
|
|
@@ -68514,7 +68637,7 @@ async function recoverStoppedMission(roots, missionId, request) {
|
|
|
68514
68637
|
throw new Error("SPECIALIST_CONTRACT_MIGRATION_INVALID: declared or installed contract changed");
|
|
68515
68638
|
}
|
|
68516
68639
|
const comparisonCatalog = await loadSpecialistMigrationComparisonCatalog(coreRoot, assets.declaration, stored.plan);
|
|
68517
|
-
const comparison = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, comparisonCatalog);
|
|
68640
|
+
const comparison = await planBoundMission(workRoot, stored.ticket.path, (/* @__PURE__ */ new Date()).toISOString(), subject.files, comparisonCatalog, stored.inputRecipe);
|
|
68518
68641
|
for (const specialist of comparison.plan.specialists) {
|
|
68519
68642
|
if (specialist.specialistId !== assets.declaration.specialistId) {
|
|
68520
68643
|
currentInputHashes[specialist.specialistId] = canonicalJsonHash({
|
|
@@ -68526,19 +68649,19 @@ async function recoverStoppedMission(roots, missionId, request) {
|
|
|
68526
68649
|
}
|
|
68527
68650
|
const provenance4 = request.disposition.kind !== "review-provenance" ? void 0 : await readRecoveryReviewBindings(workRoot, request.disposition.resolutionArtifact.path);
|
|
68528
68651
|
const resolutionArtifact = provenance4?.artifact ?? (request.disposition.kind === "review-blocker" || request.disposition.kind === "command-correction" ? await recoveryResolutionArtifact(workRoot, request.disposition.resolutionArtifact.path) : void 0);
|
|
68529
|
-
const committedSubject = provenance4 === void 0 ? void 0 : await captureMissionReviewSubject(workRoot, stored.baseCommit, true);
|
|
68530
68652
|
const opaqueContextRecovery = request.disposition.kind === "controller-defect" && request.disposition.defect === "opaque-native-context";
|
|
68531
68653
|
const recoverySpecialists = opaqueContextRecovery || request.disposition.kind === "preparation-invocation" ? migration.plan.specialists.filter((value) => value.state === "applicable" && value.stages?.includes("pre-implementation")) : migration.plan.specialists;
|
|
68532
68654
|
const observation2 = {
|
|
68533
|
-
...provenance4 === void 0 ||
|
|
68655
|
+
...provenance4 === void 0 || subject?.baseCommit === void 0 || subject.reviewedCommit === void 0 ? {} : {
|
|
68534
68656
|
reviewBindings: provenance4.bindings,
|
|
68535
68657
|
reviewSubject: {
|
|
68536
68658
|
taskId: missionId,
|
|
68537
|
-
baseCommit:
|
|
68538
|
-
reviewedCommit:
|
|
68659
|
+
baseCommit: subject.baseCommit,
|
|
68660
|
+
reviewedCommit: subject.reviewedCommit,
|
|
68539
68661
|
acceptanceCriteriaHash: stored.ticket.contentHash
|
|
68540
68662
|
}
|
|
68541
68663
|
},
|
|
68664
|
+
...implemented && (provenanceRecovery || boundedMissionReview(inspected.stream.events)) ? { reviewPolicy: "bounded-corrections-v1" } : {},
|
|
68542
68665
|
stage: implemented ? "post-implementation" : "pre-implementation",
|
|
68543
68666
|
maxRounds: 2,
|
|
68544
68667
|
evidenceDependencies: { "git:working-tree": current.project.diffHash },
|
|
@@ -68602,13 +68725,14 @@ async function dispatchMissionSpecialists(roots, input2, generatedAt = (/* @__PU
|
|
|
68602
68725
|
const inspected = current?.inspected ?? initialInspection;
|
|
68603
68726
|
requireOpenMission(inspected.stream.events);
|
|
68604
68727
|
const implemented = inspected.stream.events.some((event) => event.kind === "lead-writer.completed" && isUnknownRecord(event.payload) && event.payload.actionKind !== "run-preparation-correction");
|
|
68605
|
-
const
|
|
68606
|
-
const reviewSubject = implemented ? await captureMissionReviewSubject(workRoot, stored.baseCommit, boundedReview) : void 0;
|
|
68728
|
+
const reviewSubject = implemented ? await captureControllerReviewSubject(workRoot, stored.baseCommit, inspected.stream.events) : void 0;
|
|
68607
68729
|
const live = await planBoundMission(
|
|
68608
68730
|
workRoot,
|
|
68609
68731
|
stored.ticket.path,
|
|
68610
68732
|
generatedAt,
|
|
68611
|
-
reviewSubject?.files
|
|
68733
|
+
reviewSubject?.files,
|
|
68734
|
+
void 0,
|
|
68735
|
+
stored.inputRecipe
|
|
68612
68736
|
);
|
|
68613
68737
|
const livePlan = live.plan;
|
|
68614
68738
|
if (live.ticket.path !== stored.ticket.path || live.ticket.contentHash !== stored.ticket.contentHash) {
|
|
@@ -68639,7 +68763,7 @@ async function dispatchMissionSpecialists(roots, input2, generatedAt = (/* @__PU
|
|
|
68639
68763
|
throw new Error("SPECIALIST_CONTRACT_MIGRATION_INVALID: declared or installed contract changed");
|
|
68640
68764
|
}
|
|
68641
68765
|
const catalog = await loadSpecialistMigrationComparisonCatalog(coreRoot, assets.declaration, stored.plan);
|
|
68642
|
-
const comparison = await planBoundMission(workRoot, stored.ticket.path, generatedAt, reviewSubject.files, catalog);
|
|
68766
|
+
const comparison = await planBoundMission(workRoot, stored.ticket.path, generatedAt, reviewSubject.files, catalog, stored.inputRecipe);
|
|
68643
68767
|
for (const specialist of comparison.plan.specialists) {
|
|
68644
68768
|
if (specialist.specialistId !== assets.declaration.specialistId) {
|
|
68645
68769
|
currentInputHashes[specialist.specialistId] = canonicalJsonHash({
|
|
@@ -68674,19 +68798,6 @@ async function dispatchMissionSpecialists(roots, input2, generatedAt = (/* @__PU
|
|
|
68674
68798
|
reviewedCommit: reviewSubject.reviewedCommit,
|
|
68675
68799
|
acceptanceCriteriaHash: stored.ticket.contentHash
|
|
68676
68800
|
};
|
|
68677
|
-
if (reviewBinding2 !== void 0) {
|
|
68678
|
-
const restored = validatedRecoveredReviewEvents(inspected.stream.events);
|
|
68679
|
-
if (!restored.ok) throw new Error(`MISSION_RECOVERY_INVALID: ${restored.reasons.join("; ")}`);
|
|
68680
|
-
const hasProvenanceRecovery = inspected.stream.events.some((event) => event.kind === "mission.recovered" && objectField(objectField(objectField(event.payload, "request"), "disposition"), "kind") === "review-provenance");
|
|
68681
|
-
if (hasProvenanceRecovery) for (const event of restored.events) {
|
|
68682
|
-
if (event.kind !== "specialist.completed") continue;
|
|
68683
|
-
const receipt2 = parseSpecialistCompletionValue(objectField(event.payload, "completion"))?.review;
|
|
68684
|
-
const hash7 = objectField(event.payload, "inputHash");
|
|
68685
|
-
if (receipt2 !== void 0 && sameReviewSubject(receipt2, reviewBinding2) && typeof hash7 === "string") {
|
|
68686
|
-
currentInputHashes[event.subject] = hash7;
|
|
68687
|
-
}
|
|
68688
|
-
}
|
|
68689
|
-
}
|
|
68690
68801
|
const decision = orchestrateMissionTeam({
|
|
68691
68802
|
...reviewBinding2 === void 0 ? {} : { reviewSubject: reviewBinding2 },
|
|
68692
68803
|
plan: stored.plan,
|
|
@@ -69010,7 +69121,7 @@ Fix: ${parsed.fix}
|
|
|
69010
69121
|
const journal = roots.installRoot;
|
|
69011
69122
|
try {
|
|
69012
69123
|
if (parsed.kind === "plan") {
|
|
69013
|
-
const plan2 = await planMission(root, parsed.ticketPath);
|
|
69124
|
+
const plan2 = await planMission(root, parsed.ticketPath, void 0, "project-v1");
|
|
69014
69125
|
process.stdout.write(parsed.json ? `${JSON.stringify(plan2)}
|
|
69015
69126
|
` : `${renderPlan(plan2)}
|
|
69016
69127
|
`);
|
|
@@ -69095,7 +69206,7 @@ ${dispatched.envelopes.map((envelope) => `${envelope.agentName} ${envelope.stage
|
|
|
69095
69206
|
}
|
|
69096
69207
|
if (parsed.kind === "start") {
|
|
69097
69208
|
const baseCommit = parsed.ticketPath === void 0 ? void 0 : await missionReviewBase(root);
|
|
69098
|
-
const bound = parsed.ticketPath === void 0 ? void 0 : await planBoundMission(root, parsed.ticketPath);
|
|
69209
|
+
const bound = parsed.ticketPath === void 0 ? void 0 : await planBoundMission(root, parsed.ticketPath, void 0, void 0, void 0, "project-v1");
|
|
69099
69210
|
const plan2 = bound?.plan;
|
|
69100
69211
|
const diff = plan2 === void 0 ? await gitFiles(root) : void 0;
|
|
69101
69212
|
const stack = diff === void 0 ? void 0 : detectedStack(root, detectProfileInput(root, diff.files));
|
|
@@ -69114,7 +69225,7 @@ ${dispatched.envelopes.map((envelope) => `${envelope.agentName} ${envelope.stage
|
|
|
69114
69225
|
const controllerPlan = plan2 === void 0 ? void 0 : missionSpecialistPlan(plan2);
|
|
69115
69226
|
const ticketBinding = bound?.ticket;
|
|
69116
69227
|
const runtimeIdentity = bound === void 0 ? void 0 : coordinatorRuntimeIdentity(process.env);
|
|
69117
|
-
const routingHash = controllerPlan === void 0 ? void 0 : ticketBinding === void 0 ? void 0 : missionControllerRoutingHash(controllerPlan, ticketBinding, baseCommit);
|
|
69228
|
+
const routingHash = controllerPlan === void 0 ? void 0 : ticketBinding === void 0 ? void 0 : missionControllerRoutingHash(controllerPlan, ticketBinding, baseCommit, "project-v1");
|
|
69118
69229
|
await createMission(journal, {
|
|
69119
69230
|
missionId,
|
|
69120
69231
|
title: parsed.title,
|
|
@@ -69141,7 +69252,8 @@ ${dispatched.envelopes.map((envelope) => `${envelope.agentName} ${envelope.stage
|
|
|
69141
69252
|
missionId,
|
|
69142
69253
|
controllerPlan,
|
|
69143
69254
|
ticketBinding,
|
|
69144
|
-
baseCommit
|
|
69255
|
+
baseCommit,
|
|
69256
|
+
"project-v1"
|
|
69145
69257
|
);
|
|
69146
69258
|
if (storedHash !== routingHash) {
|
|
69147
69259
|
throw new Error("MISSION_CONTROLLER_PLAN_INVALID: routing hash changed while storing");
|