voidmachine 5.0.7 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -5605,8 +5605,8 @@ var require_cst_visit = __commonJS({
5605
5605
  visit3.REMOVE = REMOVE;
5606
5606
  visit3.itemAtPath = (cst, path3) => {
5607
5607
  let item = cst;
5608
- for (const [field9, index] of path3) {
5609
- const tok = item?.[field9];
5608
+ for (const [field11, index] of path3) {
5609
+ const tok = item?.[field11];
5610
5610
  if (tok && "items" in tok) {
5611
5611
  item = tok.items[index];
5612
5612
  } else
@@ -5616,8 +5616,8 @@ var require_cst_visit = __commonJS({
5616
5616
  };
5617
5617
  visit3.parentCollection = (cst, path3) => {
5618
5618
  const parent = visit3.itemAtPath(cst, path3.slice(0, -1));
5619
- const field9 = path3[path3.length - 1][0];
5620
- const coll = parent?.[field9];
5619
+ const field11 = path3[path3.length - 1][0];
5620
+ const coll = parent?.[field11];
5621
5621
  if (coll && "items" in coll)
5622
5622
  return coll;
5623
5623
  throw new Error("Parent collection not found");
@@ -5626,11 +5626,11 @@ var require_cst_visit = __commonJS({
5626
5626
  let ctrl = visitor(item, path3);
5627
5627
  if (typeof ctrl === "symbol")
5628
5628
  return ctrl;
5629
- for (const field9 of ["key", "value"]) {
5630
- const token = item[field9];
5629
+ for (const field11 of ["key", "value"]) {
5630
+ const token = item[field11];
5631
5631
  if (token && "items" in token) {
5632
5632
  for (let i = 0; i < token.items.length; ++i) {
5633
- const ci = _visit(Object.freeze(path3.concat([[field9, i]])), token.items[i], visitor);
5633
+ const ci = _visit(Object.freeze(path3.concat([[field11, i]])), token.items[i], visitor);
5634
5634
  if (typeof ci === "number")
5635
5635
  i = ci - 1;
5636
5636
  else if (ci === BREAK)
@@ -5640,7 +5640,7 @@ var require_cst_visit = __commonJS({
5640
5640
  i -= 1;
5641
5641
  }
5642
5642
  }
5643
- if (typeof ctrl === "function" && field9 === "key")
5643
+ if (typeof ctrl === "function" && field11 === "key")
5644
5644
  ctrl = ctrl(item, path3);
5645
5645
  }
5646
5646
  }
@@ -16438,14 +16438,14 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
16438
16438
  const shape = zod.def.shape;
16439
16439
  const propValues = {};
16440
16440
  for (const key in shape) {
16441
- const field9 = shape[key]._zod;
16442
- if (field9.values) {
16441
+ const field11 = shape[key]._zod;
16442
+ if (field11.values) {
16443
16443
  if (!Object.prototype.hasOwnProperty.call(propValues, key)) {
16444
16444
  assignProp(propValues, key, /* @__PURE__ */ new Set());
16445
16445
  }
16446
- for (const v2 of field9.values)
16446
+ for (const v2 of field11.values)
16447
16447
  propValues[key].add(v2);
16448
- if (field9.optin !== void 0)
16448
+ if (field11.optin !== void 0)
16449
16449
  propValues[key].add(void 0);
16450
16450
  }
16451
16451
  }
@@ -29437,8 +29437,8 @@ var objectProcessor = (schema, ctx, _json, params) => {
29437
29437
  }
29438
29438
  const requiredKeys = [];
29439
29439
  for (const key of Object.keys(shape)) {
29440
- const field9 = def.shape[key];
29441
- if (ctx.io === "input" ? inputOptin(field9) === void 0 : field9._zod.optout === void 0) {
29440
+ const field11 = def.shape[key];
29441
+ if (ctx.io === "input" ? inputOptin(field11) === void 0 : field11._zod.optout === void 0) {
29442
29442
  requiredKeys.push(key);
29443
29443
  }
29444
29444
  }
@@ -32864,7 +32864,7 @@ var COMMAND_CATALOG = {
32864
32864
  "help": [
32865
32865
  {
32866
32866
  "signature": "mission <sub>",
32867
- "description": "Plan a deterministic DAG, then start, resume, verify, inspect, archive, or explicitly prune an auditable local mission run."
32867
+ "description": "Plan a deterministic DAG, then start, resume, verify, inspect, archive, or explicitly prune an auditable local mission run. Inspect --usage adds local skill, hook and specialist counts."
32868
32868
  }
32869
32869
  ]
32870
32870
  },
@@ -32996,15 +32996,15 @@ var SEGMENT = /^[a-z0-9][a-z0-9._-]*$/;
32996
32996
  function isRecord(value) {
32997
32997
  return typeof value === "object" && value !== void 0 && value !== null && !Array.isArray(value);
32998
32998
  }
32999
- function segment(value, field9) {
32999
+ function segment(value, field11) {
33000
33000
  if (typeof value !== "string" || !SEGMENT.test(value)) {
33001
- throw new Error(`product identity: ${field9} must be a lowercase name without separators`);
33001
+ throw new Error(`product identity: ${field11} must be a lowercase name without separators`);
33002
33002
  }
33003
33003
  return value;
33004
33004
  }
33005
- function segments(value, field9) {
33006
- if (!Array.isArray(value)) throw new Error(`product identity: ${field9} must be a list`);
33007
- return value.map((entry, index) => segment(entry, `${field9}[${index}]`));
33005
+ function segments(value, field11) {
33006
+ if (!Array.isArray(value)) throw new Error(`product identity: ${field11} must be a list`);
33007
+ return value.map((entry, index) => segment(entry, `${field11}[${index}]`));
33008
33008
  }
33009
33009
  function formerPackages(value) {
33010
33010
  if (value === void 0) return [];
@@ -33020,16 +33020,16 @@ function formerPackages(value) {
33020
33020
  }
33021
33021
  var NAMESPACE = SEGMENT;
33022
33022
  var PREFIX = /^[A-Z][A-Z0-9_]*_$/;
33023
- function exclusive(current, deprecated, field9) {
33024
- if (deprecated.includes(current)) throw new Error(`product identity: ${current} is both current and deprecated (${field9})`);
33023
+ function exclusive(current, deprecated, field11) {
33024
+ if (deprecated.includes(current)) throw new Error(`product identity: ${current} is both current and deprecated (${field11})`);
33025
33025
  }
33026
- function pattern(value, shape, field9, rule) {
33027
- if (typeof value !== "string" || !shape.test(value)) throw new Error(`product identity: ${field9} must be ${rule}`);
33026
+ function pattern(value, shape, field11, rule) {
33027
+ if (typeof value !== "string" || !shape.test(value)) throw new Error(`product identity: ${field11} must be ${rule}`);
33028
33028
  return value;
33029
33029
  }
33030
- function patterns(value, shape, field9, rule) {
33031
- if (!Array.isArray(value)) throw new Error(`product identity: ${field9} must be a list`);
33032
- return value.map((entry, index) => pattern(entry, shape, `${field9}[${index}]`, rule));
33030
+ function patterns(value, shape, field11, rule) {
33031
+ if (!Array.isArray(value)) throw new Error(`product identity: ${field11} must be a list`);
33032
+ return value.map((entry, index) => pattern(entry, shape, `${field11}[${index}]`, rule));
33033
33033
  }
33034
33034
  function managed(namespaces, pair) {
33035
33035
  const recognized = namespaces.map(pair);
@@ -35804,6 +35804,89 @@ function parseEnvelope(event) {
35804
35804
  completion
35805
35805
  };
35806
35806
  }
35807
+ function freshReviewProofIds(events, context2) {
35808
+ return events.flatMap((event) => {
35809
+ if (event.kind !== "evidence.recorded")
35810
+ return [];
35811
+ const parsed = parseEvidence(record7(event.payload)?.["evidence"]);
35812
+ return parsed.ok && parsed.value.evidenceId === event.subject && parsed.value.missionId === event.missionId && parsed.value.status === "passed" && assessEvidence(parsed.value, context2).status === "fresh" ? [parsed.value.evidenceId] : [];
35813
+ });
35814
+ }
35815
+ function reviewField(event, key) {
35816
+ return record7(event?.payload)?.[key];
35817
+ }
35818
+ function sameNativeDispatch(left, right) {
35819
+ return left.missionId === right.missionId && left.subject === right.subject && ["stage", "reviewRound", "inputHash", "contractVersion", "reviewSubject", "reviewScope"].every((key) => reviewField(left, key) !== void 0 && reviewField(right, key) !== void 0 && canonicalJsonHash(reviewField(left, key)) === canonicalJsonHash(reviewField(right, key)));
35820
+ }
35821
+ function boundNativeRequest(events, envelope) {
35822
+ const { event, completion, contextId } = envelope;
35823
+ const receipt2 = completion.review;
35824
+ const subject = reviewField(event, "reviewSubject");
35825
+ const scope = reviewField(event, "reviewScope");
35826
+ const start = events[0];
35827
+ if (!start || !receipt2 || !isReviewSubject(subject) || !isReviewScope(scope) || !sameReviewSubject(receipt2, subject) || canonicalJsonHash(receipt2.scope) !== canonicalJsonHash(scope) || receipt2.taskId !== event.missionId || receipt2.writerId !== reviewField(start, "leadWriterId") || receipt2.provenance.kind !== "native-context" || receipt2.provenance.contextId !== contextId || contextId === receipt2.writerId || event.source !== `runtime:${String(reviewField(start, "runtime"))}` || event.subject !== completion.specialistId || reviewField(event, "contractVersion") !== completion.contractVersion)
35828
+ return void 0;
35829
+ const requests = events.filter((candidate) => candidate.kind === "specialist.requested" && candidate.seq < event.seq && candidate.source === "void-harness:mission.dispatch" && sameNativeDispatch(candidate, event) && reviewField(candidate, "planHash") === reviewField(start, "planHash") && reviewField(candidate, "runtime") === reviewField(start, "runtime"));
35830
+ const request = requests[0];
35831
+ if (requests.length !== 1 || !request)
35832
+ return void 0;
35833
+ const started = events.filter((candidate) => candidate.kind === "specialist.started" && candidate.seq > request.seq && candidate.seq < event.seq && candidate.source === event.source && sameNativeDispatch(candidate, event) && reviewField(candidate, "contextId") === contextId && (candidate.causationId === void 0 || candidate.causationId === request.eventId));
35834
+ return started.length === 1 && (event.causationId === void 0 || event.causationId === request.eventId) && (reviewField(event, "reviewInvocationEventId") === void 0 || reviewField(event, "reviewInvocationEventId") === started[0]?.eventId) ? request : void 0;
35835
+ }
35836
+ function sameMembers(actual, expected) {
35837
+ return Array.isArray(actual) && actual.length === new Set(expected).size && new Set(actual).size === actual.length && actual.every((value) => expected.includes(value));
35838
+ }
35839
+ function authorizedTargetedRequest(events, request, history) {
35840
+ const original = history[0]?.completion.review;
35841
+ const previous = history.at(-1);
35842
+ const subject = reviewField(request, "reviewSubject");
35843
+ const scope = reviewField(request, "reviewScope");
35844
+ if (!original || !previous || !isReviewSubject(subject) || !isReviewScope(scope) || scope.kind !== "targeted" || subject.taskId !== original.taskId || subject.baseCommit !== original.baseCommit || subject.acceptanceCriteriaHash !== original.acceptanceCriteriaHash || reviewField(request, "contractVersion") !== previous.completion.contractVersion)
35845
+ return false;
35846
+ const blockers = history.flatMap((item) => item.completion.findings).filter((item) => item.classification === "blocking");
35847
+ if (blockers.length === 0 || !sameMembers(scope.findingIds, blockers.map((item) => item.id)) || !sameMembers(scope.affectedPaths, blockers.flatMap((item) => item.evidence.map((proof4) => proof4.path))))
35848
+ return false;
35849
+ const writers = events.filter((event) => event.kind === "lead-writer.completed" && event.seq > previous.event.seq && event.seq < request.seq);
35850
+ const writer = writers[0];
35851
+ const correction = events.find((event) => event.eventId === reviewField(writer ?? request, "requestEventId"));
35852
+ const count = events.filter((event) => event.kind === "lead-writer.completed" && event.seq < request.seq && reviewField(event, "actionKind") === "run-correction").length;
35853
+ if (writers.length !== 1 || !writer || !correction || count < 1 || count > 2 || reviewField(request, "reviewRound") !== count + 1 || correction.kind !== "lead-writer.requested" || correction.source !== "void-harness:mission.dispatch" || correction.seq <= previous.event.seq || correction.seq >= writer.seq || correction.subject !== original.writerId || writer.subject !== original.writerId || writer.source !== original.writerId || writer.causationId !== correction.eventId || reviewField(writer, "actionKind") !== "run-correction" || reviewField(writer, "planHash") !== reviewField(events[0], "planHash") || reviewField(writer, "implementationRound") !== count + 1 || !["actionKind", "planHash", "writerId", "implementationRound"].every((key) => reviewField(writer, key) === reviewField(correction, key)))
35854
+ return false;
35855
+ const open11 = reconcileReviewFindings(history, freshReviewProofIds(events.filter((event) => event.seq < correction.seq), { dependencies: {} })).filter((finding) => finding.classification === "blocking");
35856
+ return open11.length > 0 && sameMembers(reviewField(correction, "findingIds"), open11.map((finding) => finding.findingId));
35857
+ }
35858
+ function canContinueNativeReview(events, request, contextId) {
35859
+ const start = events[0];
35860
+ if (!start || start.kind !== "mission.started" || reviewField(request, "planHash") !== reviewField(start, "planHash") || reviewField(request, "runtime") !== reviewField(start, "runtime") || request.kind !== "specialist.requested" || request.source !== "void-harness:mission.dispatch" || request.subject !== "core:independent-code-reviewer" || reviewField(request, "stage") !== "post-implementation" || !validNativeContextId(contextId) || events.some((event) => event.missionId !== request.missionId))
35861
+ return false;
35862
+ const history = events.filter((event) => event.kind === "specialist.completed" && event.seq < request.seq && reviewField(event, "contextId") === contextId).map(parseEnvelope);
35863
+ if (history.length === 0 || history.some((item) => !item))
35864
+ return false;
35865
+ const prior = history.filter((item) => item !== void 0);
35866
+ const first = prior[0];
35867
+ if (!first || first.completion.review?.scope.kind !== "general" || first.completion.verdict !== "changes-requested" || new Set(prior.map((item) => item.completion.completionId)).size !== prior.length || events.some((event) => event.seq < request.seq && ["specialist.started", "specialist.completed"].includes(event.kind) && reviewField(event, "contextId") === contextId && (event.subject !== request.subject || reviewField(event, "stage") !== "post-implementation")) || events.filter((event) => event.kind === "specialist.completed" && event.subject === request.subject && reviewField(event, "stage") === "post-implementation" && event.seq < request.seq).at(-1)?.eventId !== prior.at(-1)?.event.eventId)
35868
+ return false;
35869
+ for (const [index, item] of prior.entries()) {
35870
+ const bound = boundNativeRequest(events, item);
35871
+ if (!bound || item.completion.review?.reviewerId !== first.completion.review.reviewerId || index > 0 && !authorizedTargetedRequest(events, bound, prior.slice(0, index)))
35872
+ return false;
35873
+ }
35874
+ return authorizedTargetedRequest(events, request, prior);
35875
+ }
35876
+ function validNativeReviewContinuation(events, completion) {
35877
+ const envelope = parseEnvelope(completion);
35878
+ if (!envelope || !envelope.contextId)
35879
+ return false;
35880
+ const request = boundNativeRequest(events, envelope);
35881
+ const receipt2 = envelope.completion.review;
35882
+ if (!request || !receipt2 || !canContinueNativeReview(events, request, envelope.contextId) || receipt2.scope.kind !== "targeted")
35883
+ return false;
35884
+ const previous = events.filter((event) => event.kind === "specialist.completed" && event.seq < request.seq && reviewField(event, "contextId") === envelope.contextId).at(-1);
35885
+ const previousReceipt = previous && parseEnvelope(previous)?.completion.review;
35886
+ const correction = events.filter((event) => event.kind === "lead-writer.requested" && event.seq < request.seq && reviewField(event, "actionKind") === "run-correction").at(-1);
35887
+ const historicalProofIds = freshReviewProofIds(events.filter((event) => event.seq < completion.seq), { dependencies: {} });
35888
+ return receipt2.reviewerId === previousReceipt?.reviewerId && correction !== void 0 && receipt2.resolutions.every((resolution) => receipt2.scope.kind === "targeted" && receipt2.scope.findingIds.includes(resolution.findingId) && (resolution.status !== "resolved" || resolution.proofIds.every((id3) => historicalProofIds.includes(id3) && receipt2.proofIds.includes(id3) && events.some((event) => event.kind === "evidence.recorded" && event.subject === id3 && event.seq > correction.seq && event.seq < completion.seq))));
35889
+ }
35807
35890
  function collectCompletions(events, stage, expectedSource, stageStartSeqExclusive, afterSeqExclusive, beforeSeqExclusive, maxRounds, retainedSpecialists, contractMigration, correctionBatches) {
35808
35891
  const accepted = [];
35809
35892
  const retained = [];
@@ -35873,7 +35956,7 @@ function collectCompletions(events, stage, expectedSource, stageStartSeqExclusiv
35873
35956
  }
35874
35957
  const duplicateCompletion = completionIds.has(envelope.completion.completionId);
35875
35958
  const contextKey = envelope.contextId ?? (envelope.completion.review?.provenance.kind === "review-artifact" ? `artifact:${envelope.completion.review.provenance.sha256}` : void 0);
35876
- const reusedContext = contextKey !== void 0 && contextIds.has(contextKey);
35959
+ const reusedContext = contextKey !== void 0 && contextIds.has(contextKey) && !(envelope.stage === "post-implementation" && validNativeReviewContinuation(events, event));
35877
35960
  if (duplicateCompletion) {
35878
35961
  issues.push({
35879
35962
  code: "duplicate-completion",
@@ -36385,9 +36468,9 @@ function sameInvocation(left, right) {
36385
36468
  return left.subject === right.subject && ["stage", "reviewRound", "inputHash"].every((key) => field3(left, key) === field3(right, key));
36386
36469
  }
36387
36470
  function admit(input2) {
36388
- const { request, observation: observation2, stream: journal } = input2;
36471
+ const { request, observation: observation3, stream: journal } = input2;
36389
36472
  const events = journal.events;
36390
- if (!requestValue(request) || !observationValue(observation2))
36473
+ if (!requestValue(request) || !observationValue(observation3))
36391
36474
  return refuse("invalid-migration", "Use the declared bounded migration request and observed inputs");
36392
36475
  const lifecycle = projectMissionLifecycle(events);
36393
36476
  if (journal.continuity !== "complete" || journal.invalidLines > 0 || journal.duplicateEventIds > 0 || lifecycle.status === "invalid")
@@ -36406,9 +36489,9 @@ function admit(input2) {
36406
36489
  const recovered = validatedRecoveredReviewEvents(events);
36407
36490
  if (!recovered.ok)
36408
36491
  return refuse("invalid-recovery", recovered.reasons.join("; "));
36409
- const declaration = observation2.declaration;
36410
- const selected = observation2.plan.specialists.find((x3) => x3.specialistId === VISUAL);
36411
- if (request.migrationId !== declaration.id || selected?.contractVersion !== 2 || selected.state !== "applicable" || !selected.stages.includes("post-implementation") || observation2.plan.context.status !== "complete" || observation2.plan.specialists.some((x3) => x3.state === "degraded") || field3(events[0], "planHash") !== observation2.plan.planHash || `runtime:${String(field3(events[0], "runtime"))}` !== observation2.expectedSource || observation2.observedFromContractSha256 !== declaration.fromContractSha256 || observation2.observedToContractSha256 !== declaration.toContractSha256 || observation2.nativeContractVersion !== 3)
36492
+ const declaration = observation3.declaration;
36493
+ const selected = observation3.plan.specialists.find((x3) => x3.specialistId === VISUAL);
36494
+ if (request.migrationId !== declaration.id || selected?.contractVersion !== 2 || selected.state !== "applicable" || !selected.stages.includes("post-implementation") || observation3.plan.context.status !== "complete" || observation3.plan.specialists.some((x3) => x3.state === "degraded") || field3(events[0], "planHash") !== observation3.plan.planHash || `runtime:${String(field3(events[0], "runtime"))}` !== observation3.expectedSource || observation3.observedFromContractSha256 !== declaration.fromContractSha256 || observation3.observedToContractSha256 !== declaration.toContractSha256 || observation3.nativeContractVersion !== 3)
36412
36495
  return refuse("migration-contract-mismatch", "Observe the original v2 plan and declared v3 assets/native specialist");
36413
36496
  const requested = events.filter((x3) => x3.kind === "specialist.requested" && x3.subject === VISUAL);
36414
36497
  const episodeStart = events.find((x3) => x3.eventId === lifecycle.episodeId);
@@ -36422,23 +36505,23 @@ function admit(input2) {
36422
36505
  const last = writers.at(-1);
36423
36506
  if (!first || !last)
36424
36507
  return refuse("missing-implementation", "Migration applies only to an implemented post-review subject");
36425
- const contracts = Object.fromEntries(observation2.plan.specialists.map((x3) => [x3.specialistId, x3.contractVersion]));
36508
+ const contracts = Object.fromEntries(observation3.plan.specialists.map((x3) => [x3.specialistId, x3.contractVersion]));
36426
36509
  const review = reduceReviewLoop({
36427
36510
  events: recovered.events,
36428
36511
  stage: "post-implementation",
36429
- expectedSource: observation2.expectedSource,
36512
+ expectedSource: observation3.expectedSource,
36430
36513
  stageStartSeqExclusive: first.seq,
36431
36514
  afterSeqExclusive: last.seq,
36432
- requiredSpecialists: observation2.plan.specialists.filter((x3) => x3.state === "applicable" && x3.stages.includes("post-implementation")).map((x3) => x3.specialistId),
36515
+ requiredSpecialists: observation3.plan.specialists.filter((x3) => x3.state === "applicable" && x3.stages.includes("post-implementation")).map((x3) => x3.specialistId),
36433
36516
  contractVersions: contracts,
36434
- currentInputHashes: observation2.currentInputHashes,
36435
- maxRounds: observation2.maxRounds
36517
+ currentInputHashes: observation3.currentInputHashes,
36518
+ maxRounds: observation3.maxRounds
36436
36519
  });
36437
36520
  if (review.issues.length > 0)
36438
36521
  return refuse("invalid-review", review.issues.map((x3) => x3.detail).join("; "));
36439
36522
  const previous = recovered.events.filter((x3) => x3.subject === VISUAL && x3.kind === "specialist.completed" && field3(x3, "stage") === "post-implementation");
36440
36523
  const reviewRound = review.reviewRound + (previous.some((x3) => x3.seq > last.seq) ? 1 : 0);
36441
- if (reviewRound > observation2.maxRounds)
36524
+ if (reviewRound > observation3.maxRounds)
36442
36525
  return refuse("review-budget-exhausted", "Migration grants no additional review round");
36443
36526
  const proofs = events.flatMap((event) => {
36444
36527
  if (event.kind !== "evidence.recorded")
@@ -36448,10 +36531,10 @@ function admit(input2) {
36448
36531
  });
36449
36532
  const obligations = reduceEvidenceObligations({
36450
36533
  events,
36451
- expectedSource: observation2.expectedSource,
36534
+ expectedSource: observation3.expectedSource,
36452
36535
  phase: "post-implementation",
36453
36536
  proofs,
36454
- evidenceContext: { dependencies: observation2.evidenceDependencies ?? {} }
36537
+ evidenceContext: { dependencies: observation3.evidenceDependencies ?? {} }
36455
36538
  });
36456
36539
  if (obligations.issues.length > 0)
36457
36540
  return refuse("invalid-evidence", obligations.issues.map((x3) => x3.detail).join("; "));
@@ -36459,7 +36542,7 @@ function admit(input2) {
36459
36542
  schemaVersion: 1,
36460
36543
  request,
36461
36544
  requestHash: canonicalJsonHash(request),
36462
- observation: observation2,
36545
+ observation: observation3,
36463
36546
  ...lifecycle.status === "closed" ? { recovery: {
36464
36547
  closureEventId: lifecycle.closure.eventId,
36465
36548
  previousEpisodeId: lifecycle.episodeId
@@ -36474,11 +36557,11 @@ function admit(input2) {
36474
36557
  toVersion: 3,
36475
36558
  fromContractSha256: declaration.fromContractSha256,
36476
36559
  toContractSha256: declaration.toContractSha256,
36477
- reviewSubjectHash: observation2.reviewSubjectHash,
36478
- targetInputHash: observation2.targetInputHash,
36479
- nativeAgentSha256: observation2.nativeAgentSha256,
36560
+ reviewSubjectHash: observation3.reviewSubjectHash,
36561
+ targetInputHash: observation3.targetInputHash,
36562
+ nativeAgentSha256: observation3.nativeAgentSha256,
36480
36563
  reviewRound,
36481
- remainingRounds: observation2.maxRounds - reviewRound + 1,
36564
+ remainingRounds: observation3.maxRounds - reviewRound + 1,
36482
36565
  supersededRequestEventIds: requested.filter((x3) => !starts.some((start) => sameInvocation(start, x3))).map((x3) => x3.eventId),
36483
36566
  supersededCompletionEventIds: events.filter((x3) => x3.kind === "specialist.completed" && x3.subject === VISUAL).map((x3) => x3.eventId),
36484
36567
  pendingAuthorObligationIds: obligations.obligations.filter((x3) => x3.specialistId === VISUAL && x3.due === "current-review" && !x3.discharged).map((x3) => x3.obligationId),
@@ -36494,10 +36577,10 @@ function validatedSpecialistContractMigrations(events, plan2) {
36494
36577
  return { ok: true, plan: plan2, events };
36495
36578
  const migration = migrations[0];
36496
36579
  const request = field3(migration, "request");
36497
- const observation2 = field3(migration, "observation");
36498
- if (migrations.length !== 1 || projectMissionLifecycle(events).status === "invalid" || migration.source !== "void-harness:mission.migrate-specialist" || migration.subject !== VISUAL || !requestValue(request) || !observationValue(observation2) || canonicalJsonHash(observation2.plan) !== canonicalJsonHash(plan2))
36580
+ const observation3 = field3(migration, "observation");
36581
+ if (migrations.length !== 1 || projectMissionLifecycle(events).status === "invalid" || migration.source !== "void-harness:mission.migrate-specialist" || migration.subject !== VISUAL || !requestValue(request) || !observationValue(observation3) || canonicalJsonHash(observation3.plan) !== canonicalJsonHash(plan2))
36499
36582
  return { ok: false, reasons: ["Migration receipt does not match its original plan or producer"] };
36500
- const decision = admit({ stream: stream(events.slice(0, migration.seq - 1)), request, observation: observation2 });
36583
+ const decision = admit({ stream: stream(events.slice(0, migration.seq - 1)), request, observation: observation3 });
36501
36584
  if (decision.kind !== "migrate" || canonicalJsonHash(decision.receipt) !== canonicalJsonHash(migration.payload)) {
36502
36585
  return { ok: false, reasons: ["Migration receipt does not reproduce admission from its journal prefix"] };
36503
36586
  }
@@ -36533,10 +36616,10 @@ function validatedSpecialistContractMigrationBoundary(events) {
36533
36616
  const migration = events.find((event) => event.kind === "specialist.contract-migrated");
36534
36617
  if (migration === void 0)
36535
36618
  return { ok: true };
36536
- const observation2 = field3(migration, "observation");
36537
- if (!observationValue(observation2))
36619
+ const observation3 = field3(migration, "observation");
36620
+ if (!observationValue(observation3))
36538
36621
  return { ok: false, reasons: ["Migration observation is invalid"] };
36539
- const validated = validatedSpecialistContractMigrations(events, observation2.plan);
36622
+ const validated = validatedSpecialistContractMigrations(events, observation3.plan);
36540
36623
  if (!validated.ok)
36541
36624
  return validated;
36542
36625
  return { ok: true, ...validated.migration === void 0 ? {} : { migration: validated.migration } };
@@ -36565,10 +36648,10 @@ function matchesRequest(completion, request) {
36565
36648
  }
36566
36649
  function opaqueNativeContextDefect(input2) {
36567
36650
  const { events } = input2.stream;
36568
- const { observation: observation2 } = input2;
36651
+ const { observation: observation3 } = input2;
36569
36652
  const start = events[0];
36570
36653
  const closure = events.at(-1);
36571
- if (start === void 0 || closure?.kind !== "mission.closed" || closure.source !== "void-harness:mission.dispatch" || start.source !== "void-harness:mission" || field4(start, "mode") !== "team" || field4(start, "runtime") !== "codex" || field4(start, "runtimeAttested") !== true || observation2.expectedSource !== "runtime:codex" || observation2.stage !== "pre-implementation" || !/^sha256:[a-f0-9]{64}$/.test(String(field4(start, "planHash"))))
36654
+ if (start === void 0 || closure?.kind !== "mission.closed" || closure.source !== "void-harness:mission.dispatch" || start.source !== "void-harness:mission" || field4(start, "mode") !== "team" || field4(start, "runtime") !== "codex" || field4(start, "runtimeAttested") !== true || observation3.expectedSource !== "runtime:codex" || observation3.stage !== "pre-implementation" || !/^sha256:[a-f0-9]{64}$/.test(String(field4(start, "planHash"))))
36572
36655
  return false;
36573
36656
  const panel = events.slice(1, -1);
36574
36657
  if (panel.some((event) => !["specialist.requested", "specialist.started", "specialist.completed"].includes(event.kind) || field4(event, "stage") !== "pre-implementation" || field4(event, "reviewRound") !== 1))
@@ -36582,7 +36665,7 @@ function opaqueNativeContextDefect(input2) {
36582
36665
  return false;
36583
36666
  return completed.every(({ event, completion }) => {
36584
36667
  const context2 = field4(event, "contextId");
36585
- if (!validNativeContextId(context2) || event.source !== observation2.expectedSource || completion.verdict !== "pass" || completion.findings.length > 0 || completion.evidenceRequests.length > 0 || completion.limitations.length > 0 || completion.specialistId !== event.subject || completion.contractVersion !== observation2.contractVersions[event.subject] || field4(event, "contractVersion") !== completion.contractVersion || field4(event, "inputHash") !== observation2.currentInputHashes[event.subject])
36668
+ if (!validNativeContextId(context2) || event.source !== observation3.expectedSource || completion.verdict !== "pass" || completion.findings.length > 0 || completion.evidenceRequests.length > 0 || completion.limitations.length > 0 || completion.specialistId !== event.subject || completion.contractVersion !== observation3.contractVersions[event.subject] || field4(event, "contractVersion") !== completion.contractVersion || field4(event, "inputHash") !== observation3.currentInputHashes[event.subject])
36586
36669
  return false;
36587
36670
  const requested = requests.find((request) => matchesRequest(event, request) && request.seq < event.seq && field4(request, "planHash") === field4(start, "planHash") && field4(request, "runtime") === "codex" && field4(request, "contractVersion") === completion.contractVersion);
36588
36671
  if (requested === void 0)
@@ -36592,9 +36675,20 @@ function opaqueNativeContextDefect(input2) {
36592
36675
  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));
36593
36676
  });
36594
36677
  }
36678
+ function targetedReviewContextDefect(input2) {
36679
+ const { events } = input2.stream;
36680
+ const { observation: observation3 } = input2;
36681
+ const start = events[0];
36682
+ const closure = events.at(-1);
36683
+ const current = completions(events).filter((item) => field4(item.event, "stage") === "post-implementation").at(-1);
36684
+ const receipt2 = current?.completion.review;
36685
+ if (!start || closure?.kind !== "mission.closed" || closure.source !== "void-harness:mission.dispatch" || start.kind !== "mission.started" || start.source !== "void-harness:mission" || field4(start, "runtimeAttested") !== true || observation3.stage !== "post-implementation" || observation3.reviewPolicy !== "bounded-corrections-v1" || !observation3.reviewSubject || !current || !receipt2 || !sameReviewSubject(receipt2, observation3.reviewSubject) || current.completion.verdict !== "pass" || current.event.source !== observation3.expectedSource || field4(current.event, "inputHash") !== observation3.currentInputHashes[current.event.subject] || current.completion.contractVersion !== observation3.contractVersions[current.event.subject])
36686
+ return false;
36687
+ return validNativeReviewContinuation(events, current.event);
36688
+ }
36595
36689
  function preparationInvocationReplacement(input2) {
36596
36690
  const { events } = input2.stream;
36597
- const { observation: observation2, request } = input2;
36691
+ const { observation: observation3, request } = input2;
36598
36692
  if (request.disposition.kind !== "preparation-invocation")
36599
36693
  return false;
36600
36694
  const start = events[0];
@@ -36603,7 +36697,7 @@ function preparationInvocationReplacement(input2) {
36603
36697
  const writers = events.filter((event) => event.kind === "lead-writer.completed");
36604
36698
  const writer = writers[0];
36605
36699
  const writerRequest = writerRequests[0];
36606
- 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)))
36700
+ 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"))}` !== observation3.expectedSource || !/^sha256:[a-f0-9]{64}$/.test(String(field4(start, "planHash"))) || observation3.stage !== "pre-implementation" || observation3.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)))
36607
36701
  return false;
36608
36702
  const allowed = [
36609
36703
  "mission.started",
@@ -36622,7 +36716,7 @@ function preparationInvocationReplacement(input2) {
36622
36716
  ];
36623
36717
  if (events.some((event) => !allowed.includes(event.kind)))
36624
36718
  return false;
36625
- const required2 = Object.keys(observation2.contractVersions);
36719
+ const required2 = Object.keys(observation3.contractVersions);
36626
36720
  const panel = completions(events);
36627
36721
  const invocations = events.filter((event) => ["specialist.requested", "specialist.started", "specialist.completed"].includes(event.kind));
36628
36722
  if (required2.length === 0 || panel.length !== required2.length * 2 || invocations.length !== panel.length * 3)
@@ -36637,13 +36731,13 @@ function preparationInvocationReplacement(input2) {
36637
36731
  if (matching.length !== 1 || item === void 0)
36638
36732
  return false;
36639
36733
  const { event, completion } = item;
36640
- 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)
36734
+ if (event.source !== observation3.expectedSource || field4(event, "stage") !== "pre-implementation" || completion.specialistId !== specialist || completion.contractVersion !== observation3.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") !== observation3.currentInputHashes[specialist]) || round === 1 && event.seq >= writerRequest.seq)
36641
36735
  return false;
36642
36736
  const requests = invocations.filter((candidate) => matchesRequest(event, candidate));
36643
36737
  const requested = requests[0];
36644
36738
  const starts = invocations.filter((candidate) => candidate.kind === "specialist.started" && candidate.subject === specialist && field4(candidate, "reviewRound") === round);
36645
36739
  const started = starts[0];
36646
- 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)))
36740
+ 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 !== observation3.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)))
36647
36741
  return false;
36648
36742
  }
36649
36743
  }
@@ -36655,12 +36749,12 @@ function preparationInvocationReplacement(input2) {
36655
36749
  });
36656
36750
  const obligations = reduceEvidenceObligations({
36657
36751
  events,
36658
- expectedSource: observation2.expectedSource,
36752
+ expectedSource: observation3.expectedSource,
36659
36753
  phase: "pre-implementation",
36660
36754
  proofs,
36661
36755
  evidenceContext: {
36662
36756
  missionId: start.missionId,
36663
- dependencies: observation2.evidenceDependencies ?? {}
36757
+ dependencies: observation3.evidenceDependencies ?? {}
36664
36758
  }
36665
36759
  });
36666
36760
  if (obligations.issues.length > 0 || obligations.blockingObligationIds.length > 0)
@@ -36668,13 +36762,13 @@ function preparationInvocationReplacement(input2) {
36668
36762
  const review = reduceReviewLoop({
36669
36763
  events,
36670
36764
  stage: "pre-implementation",
36671
- expectedSource: observation2.expectedSource,
36765
+ expectedSource: observation3.expectedSource,
36672
36766
  stageStartSeqExclusive: start.seq,
36673
36767
  afterSeqExclusive: writer.seq,
36674
36768
  requiredSpecialists: required2.filter(specialistId2),
36675
- contractVersions: observation2.contractVersions,
36676
- currentInputHashes: observation2.currentInputHashes,
36677
- maxRounds: observation2.maxRounds
36769
+ contractVersions: observation3.contractVersions,
36770
+ currentInputHashes: observation3.currentInputHashes,
36771
+ maxRounds: observation3.maxRounds
36678
36772
  });
36679
36773
  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));
36680
36774
  }
@@ -36742,33 +36836,33 @@ function specialistId2(value) {
36742
36836
  }
36743
36837
  function validProvenanceRecovery(input2, existing, afterSeqExclusive = 0) {
36744
36838
  const disposition = input2.request.disposition;
36745
- const observation2 = input2.observation;
36746
- const bindings = observation2.reviewBindings;
36747
- if (disposition.kind !== "review-provenance" || observation2.stage !== "post-implementation" || observation2.reviewSubject === void 0 || bindings === void 0 || bindings.length === 0 || bindings.length !== disposition.completionEventIds.length || new Set(disposition.completionEventIds).size !== bindings.length || observation2.resolutionArtifact?.path !== disposition.resolutionArtifact.path || observation2.resolutionArtifact.sha256 !== disposition.resolutionArtifact.sha256)
36839
+ const observation3 = input2.observation;
36840
+ const bindings = observation3.reviewBindings;
36841
+ if (disposition.kind !== "review-provenance" || observation3.stage !== "post-implementation" || observation3.reviewSubject === void 0 || bindings === void 0 || bindings.length === 0 || bindings.length !== disposition.completionEventIds.length || new Set(disposition.completionEventIds).size !== bindings.length || observation3.resolutionArtifact?.path !== disposition.resolutionArtifact.path || observation3.resolutionArtifact.sha256 !== disposition.resolutionArtifact.sha256)
36748
36842
  return false;
36749
36843
  const events = input2.stream.events;
36750
36844
  const start = events[0];
36751
36845
  if (start === void 0)
36752
36846
  return false;
36753
36847
  const writerId = field4(start, "leadWriterId");
36754
- const observedSubject = observation2.reviewSubject;
36848
+ const observedSubject = observation3.reviewSubject;
36755
36849
  return bindings.every((binding3) => {
36756
36850
  const original = existing.find((item) => item.event.eventId === binding3.completionEventId);
36757
- 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"))
36851
+ 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 !== observation3.expectedSource || original.completion.verdict !== "pass" || original.completion.findings.some((finding) => finding.classification !== "advisory") || original.completion.contractVersion !== observation3.contractVersions[original.event.subject] || field4(original.event, "inputHash") !== observation3.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"))
36758
36852
  return false;
36759
- 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);
36760
- 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)));
36853
+ 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"))}` === observation3.expectedSource);
36854
+ return requested !== void 0 && events.some((event) => event.kind === "specialist.started" && event.source === observation3.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)));
36761
36855
  });
36762
36856
  }
36763
36857
  function pendingPreparationClarification(input2, previousRecovery) {
36764
- const { stream: stream2, request, observation: observation2 } = input2;
36858
+ const { stream: stream2, request, observation: observation3 } = input2;
36765
36859
  const precedingRecovery = stream2.events.filter((event) => event.kind === "mission.recovered" && event.seq < previousRecovery.seq).at(-1);
36766
36860
  if (precedingRecovery !== void 0 && !stream2.events.some((event) => event.kind === "lead-writer.completed" && event.seq > precedingRecovery.seq && event.seq < previousRecovery.seq))
36767
36861
  return false;
36768
36862
  const priorRequest = field4(previousRecovery, "request");
36769
36863
  const priorDisposition = priorRequest !== void 0 && record10(priorRequest) ? priorRequest["disposition"] : void 0;
36770
36864
  const priorObservation = field4(previousRecovery, "observation");
36771
- if (observation2.stage !== "pre-implementation" || request.disposition.kind !== "review-blocker" || field4(previousRecovery, "nextAction") !== "clarification" || priorObservation === void 0 || !record10(priorObservation) || priorObservation["stage"] !== "pre-implementation" || priorDisposition === void 0 || !record10(priorDisposition) || priorDisposition["kind"] !== "review-blocker" || canonicalJsonHash(priorDisposition["completionEventIds"]) !== canonicalJsonHash(request.disposition.completionEventIds))
36865
+ if (observation3.stage !== "pre-implementation" || request.disposition.kind !== "review-blocker" || field4(previousRecovery, "nextAction") !== "clarification" || priorObservation === void 0 || !record10(priorObservation) || priorObservation["stage"] !== "pre-implementation" || priorDisposition === void 0 || !record10(priorDisposition) || priorDisposition["kind"] !== "review-blocker" || canonicalJsonHash(priorDisposition["completionEventIds"]) !== canonicalJsonHash(request.disposition.completionEventIds))
36772
36866
  return false;
36773
36867
  const intervening = stream2.events.filter((event) => event.seq > previousRecovery.seq);
36774
36868
  if (intervening.length !== 1 || intervening[0]?.kind !== "mission.closed" || intervening[0].source !== "void-harness:mission.dispatch")
@@ -36781,10 +36875,10 @@ function pendingPreparationClarification(input2, previousRecovery) {
36781
36875
  });
36782
36876
  const obligations = reduceEvidenceObligations({
36783
36877
  events: stream2.events,
36784
- expectedSource: observation2.expectedSource,
36878
+ expectedSource: observation3.expectedSource,
36785
36879
  phase: "pre-implementation",
36786
36880
  proofs,
36787
- evidenceContext: { dependencies: observation2.evidenceDependencies ?? {} }
36881
+ evidenceContext: { dependencies: observation3.evidenceDependencies ?? {} }
36788
36882
  });
36789
36883
  const blocking = new Set(obligations.blockingObligationIds);
36790
36884
  const completionEventIds = request.disposition.completionEventIds;
@@ -36840,7 +36934,7 @@ function validEvidenceDispositionRecovery(input2) {
36840
36934
  });
36841
36935
  }
36842
36936
  function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
36843
- const { stream: stream2, request, observation: observation2 } = input2;
36937
+ const { stream: stream2, request, observation: observation3 } = input2;
36844
36938
  const events = stream2.events;
36845
36939
  if (stream2.continuity !== "complete" || stream2.duplicateEventIds > 0 || stream2.invalidLines > 0) {
36846
36940
  return refuse2("invalid-journal", "Restore a complete unambiguous original journal before recovery");
@@ -36860,35 +36954,36 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
36860
36954
  if (request.disposition.kind === "evidence-disposition" && !validEvidenceDispositionRecovery(input2)) {
36861
36955
  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");
36862
36956
  }
36863
- const existing = completions(events).filter((item) => field4(item.event, "stage") === observation2.stage);
36957
+ const existing = completions(events).filter((item) => field4(item.event, "stage") === observation3.stage);
36864
36958
  const previousRecovery = events.filter((event) => event.kind === "mission.recovered").at(-1);
36865
36959
  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)) {
36866
36960
  return refuse2("no-recovery-progress", "Record actual corrective progress before reopening another stopped episode");
36867
36961
  }
36868
36962
  const disposition = request.disposition;
36869
36963
  const replacement = disposition.kind === "preparation-invocation";
36964
+ const targetedContext = disposition.kind === "controller-defect" && disposition.defect === "targeted-review-context";
36870
36965
  if (replacement && !preparationInvocationReplacement(input2)) {
36871
36966
  return refuse2("invalid-preparation-invocation", "Name exactly the reused-context preparation completions with intact invocation bindings; replacement is one-time and retains round two");
36872
36967
  }
36873
- const roundCorrections = replacement ? [] : partialFanoutCorrections(projectedHistory);
36874
- const inadmissible = replacement ? disposition.completionEventIds : staleDispatchCompletions(projectedHistory);
36875
- if (disposition.kind === "controller-defect" && (disposition.defect === "partial-fanout-round" ? roundCorrections.length === 0 : disposition.defect === "stale-input-dispatch" ? inadmissible.length === 0 : !opaqueNativeContextDefect(input2))) {
36968
+ const roundCorrections = replacement || targetedContext ? [] : partialFanoutCorrections(projectedHistory);
36969
+ const inadmissible = replacement ? disposition.completionEventIds : targetedContext ? [] : staleDispatchCompletions(projectedHistory);
36970
+ if (disposition.kind === "controller-defect" && (disposition.defect === "partial-fanout-round" ? roundCorrections.length === 0 : disposition.defect === "stale-input-dispatch" ? inadmissible.length === 0 : targetedContext ? !targetedReviewContextDefect(input2) : !opaqueNativeContextDefect(input2))) {
36876
36971
  return refuse2("unproven-controller-defect", "The journal must prove the requested controller defect; do not reset its budget");
36877
36972
  }
36878
36973
  if (disposition.kind === "review-provenance" && !validProvenanceRecovery(input2, existing)) {
36879
36974
  return refuse2("invalid-review-provenance", "Preserve the actual independent invocation, exact subject, original passing result and contract; provenance cannot upgrade degraded evidence");
36880
36975
  }
36881
36976
  if (disposition.kind === "command-correction") {
36882
- if (observation2.resolutionArtifact?.path !== disposition.resolutionArtifact.path || observation2.resolutionArtifact.sha256 !== disposition.resolutionArtifact.sha256) {
36977
+ if (observation3.resolutionArtifact?.path !== disposition.resolutionArtifact.path || observation3.resolutionArtifact.sha256 !== disposition.resolutionArtifact.sha256) {
36883
36978
  return refuse2("stale-resolution-artifact", "Read and hash the command correction artifact again before recovery");
36884
36979
  }
36885
- if (!validCommandEvidenceCorrections(events, disposition.pairs, observation2.evidenceDependencies ?? {})) {
36980
+ if (!validCommandEvidenceCorrections(events, disposition.pairs, observation3.evidenceDependencies ?? {})) {
36886
36981
  return refuse2("invalid-command-correction", "Name intact fresh command proofs with exact argv correspondence; exit 127 or a matching basename cannot authorize replacement");
36887
36982
  }
36888
36983
  }
36889
36984
  if (disposition.kind === "review-blocker") {
36890
36985
  let eligible = existing;
36891
- if (observation2.stage === "post-implementation" && disposition.completionEventIds.some((id3) => !existing.some((item) => item.event.eventId === id3))) {
36986
+ if (observation3.stage === "post-implementation" && disposition.completionEventIds.some((id3) => !existing.some((item) => item.event.eventId === id3))) {
36892
36987
  const proofs = events.flatMap((event) => {
36893
36988
  if (event.kind !== "evidence.recorded")
36894
36989
  return [];
@@ -36897,43 +36992,43 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
36897
36992
  });
36898
36993
  const obligations = reduceEvidenceObligations({
36899
36994
  events,
36900
- expectedSource: observation2.expectedSource,
36901
- phase: observation2.stage,
36995
+ expectedSource: observation3.expectedSource,
36996
+ phase: observation3.stage,
36902
36997
  proofs,
36903
36998
  evidenceContext: {
36904
36999
  missionId: events[0].missionId,
36905
- dependencies: observation2.evidenceDependencies ?? {}
37000
+ dependencies: observation3.evidenceDependencies ?? {}
36906
37001
  }
36907
37002
  });
36908
37003
  if (obligations.issues.length > 0)
36909
37004
  return refuse2("invalid-evidence", "Resolve invalid author dispositions before requesting recovery");
36910
37005
  const blocking = new Set(obligations.blockingObligationIds);
36911
37006
  const owners = new Set(obligations.obligations.filter((item) => blocking.has(item.obligationId)).map((item) => item.completionEventId));
36912
- eligible = [...existing, ...completions(events).filter((item) => field4(item.event, "stage") === "pre-implementation" && owners.has(item.event.eventId) && observation2.contractVersions[item.event.subject] !== void 0)];
37007
+ eligible = [...existing, ...completions(events).filter((item) => field4(item.event, "stage") === "pre-implementation" && owners.has(item.event.eventId) && observation3.contractVersions[item.event.subject] !== void 0)];
36913
37008
  }
36914
37009
  const blockers = eligible.filter(({ event, completion }) => disposition.completionEventIds.includes(event.eventId) && (completion.verdict !== "pass" || completion.findings.length > 0 || completion.evidenceRequests.length > 0 || completion.limitations.length > 0));
36915
37010
  if (blockers.length !== disposition.completionEventIds.length || blockers.length === 0 || new Set(disposition.completionEventIds).size !== blockers.length) {
36916
37011
  return refuse2("missing-review-blocker", "Name existing unresolved review completions before requesting clarification");
36917
37012
  }
36918
- if (observation2.resolutionArtifact?.path !== disposition.resolutionArtifact.path || observation2.resolutionArtifact.sha256 !== disposition.resolutionArtifact.sha256) {
37013
+ if (observation3.resolutionArtifact?.path !== disposition.resolutionArtifact.path || observation3.resolutionArtifact.sha256 !== disposition.resolutionArtifact.sha256) {
36919
37014
  return refuse2("stale-resolution-artifact", "Read and hash the resolution artifact again before recovery");
36920
37015
  }
36921
37016
  }
36922
37017
  const projected = applyRoundCorrections(projectedHistory, roundCorrections).filter((event) => !inadmissible.includes(event.eventId));
36923
- const required2 = Object.keys(observation2.contractVersions).filter(specialistId2);
37018
+ const required2 = Object.keys(observation3.contractVersions).filter(specialistId2);
36924
37019
  const writers = projected.filter((event) => event.kind === "lead-writer.completed");
36925
- const stageStart = observation2.stage === "post-implementation" ? writers.find((event) => field4(event, "actionKind") !== "run-preparation-correction")?.seq : replacement ? events[0]?.seq : void 0;
36926
- const lastWriter = observation2.stage === "post-implementation" || replacement ? writers.at(-1)?.seq : void 0;
37020
+ const stageStart = observation3.stage === "post-implementation" ? writers.find((event) => field4(event, "actionKind") !== "run-preparation-correction")?.seq : replacement ? events[0]?.seq : void 0;
37021
+ const lastWriter = observation3.stage === "post-implementation" || replacement ? writers.at(-1)?.seq : void 0;
36927
37022
  const migration = validatedSpecialistContractMigrationBoundary(events);
36928
37023
  if (!migration.ok)
36929
37024
  return refuse2("invalid-migration-receipt", migration.reasons.join("; "));
36930
- const boundary = observation2.stage === "post-implementation" ? migration.migration : void 0;
36931
- if (boundary !== void 0 && observation2.contractVersions[boundary.receipt.specialistId] !== boundary.receipt.toVersion) {
37025
+ const boundary = observation3.stage === "post-implementation" ? migration.migration : void 0;
37026
+ if (boundary !== void 0 && observation3.contractVersions[boundary.receipt.specialistId] !== boundary.receipt.toVersion) {
36932
37027
  return refuse2("inconsistent-review", "Recovery must observe the authenticated effective specialist contract");
36933
37028
  }
36934
37029
  const reviewInput = {
36935
- stage: observation2.stage,
36936
- expectedSource: observation2.expectedSource,
37030
+ stage: observation3.stage,
37031
+ expectedSource: observation3.expectedSource,
36937
37032
  ...boundary === void 0 ? {} : { contractMigration: {
36938
37033
  specialistId: boundary.receipt.specialistId,
36939
37034
  afterSeq: boundary.seq,
@@ -36942,9 +37037,12 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
36942
37037
  ...stageStart === void 0 ? {} : { stageStartSeqExclusive: stageStart },
36943
37038
  ...lastWriter === void 0 ? {} : { afterSeqExclusive: lastWriter },
36944
37039
  requiredSpecialists: required2,
36945
- contractVersions: observation2.contractVersions,
36946
- currentInputHashes: observation2.currentInputHashes,
36947
- ...observation2.reviewPolicy === "bounded-corrections-v1" ? BOUNDED_REVIEW_BUDGET : { maxRounds: observation2.maxRounds }
37040
+ contractVersions: observation3.contractVersions,
37041
+ currentInputHashes: observation3.currentInputHashes,
37042
+ ...targetedContext ? { validProofIds: freshReviewProofIds(projected, {
37043
+ dependencies: observation3.evidenceDependencies ?? {}
37044
+ }) } : {},
37045
+ ...observation3.reviewPolicy === "bounded-corrections-v1" ? BOUNDED_REVIEW_BUDGET : { maxRounds: observation3.maxRounds }
36948
37046
  };
36949
37047
  const originalReview = reduceReviewLoop({ ...reviewInput, events: projectedHistory });
36950
37048
  if (originalReview.issues.some((issue4) => replacement ? issue4.code !== "reused-context" || !inadmissible.includes(issue4.eventId) : issue4.code !== "wrong-review-round")) {
@@ -36957,14 +37055,17 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
36957
37055
  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)))) {
36958
37056
  return refuse2("incomplete-required-panel", "Every required preparation specialist must have its original matching PASS triplet before recovery");
36959
37057
  }
36960
- 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"))));
36961
- if (!replacement && disposition.kind !== "review-provenance" && consumedRounds >= reviewInput.maxRounds)
37058
+ if (targetedContext && !review.readyForVerdict) {
37059
+ return refuse2("unproven-controller-defect", "The retained targeted review must resolve every blocking finding with current evidence before verification");
37060
+ }
37061
+ const consumedRounds = Math.max(0, ...(replacement ? projectedHistory : projected).filter((event) => ["specialist.completed", "specialist.failed"].includes(event.kind) && field4(event, "stage") === observation3.stage).map((event) => Number(field4(event, "reviewRound"))));
37062
+ if (!replacement && !targetedContext && disposition.kind !== "review-provenance" && consumedRounds >= reviewInput.maxRounds)
36962
37063
  return refuse2("review-budget-exhausted", "The real review budget is exhausted; recovery cannot reset it");
36963
37064
  const consumedCorrectionBatches = projected.filter((event) => event.kind === "lead-writer.completed" && field4(event, "actionKind") === "run-correction").length;
36964
- if (disposition.kind === "review-provenance" && consumedCorrectionBatches > 2) {
37065
+ if ((targetedContext || disposition.kind === "review-provenance") && consumedCorrectionBatches > 2) {
36965
37066
  return refuse2("review-budget-exhausted", "The real correction budget is exhausted; recovery cannot reset it");
36966
37067
  }
36967
- const preserved = existing.filter((item) => !inadmissible.includes(item.event.eventId) && item.completion.contractVersion === observation2.contractVersions[item.event.subject] && field4(item.event, "inputHash") === observation2.currentInputHashes[item.event.subject]);
37068
+ const preserved = targetedContext ? existing : existing.filter((item) => !inadmissible.includes(item.event.eventId) && item.completion.contractVersion === observation3.contractVersions[item.event.subject] && field4(item.event, "inputHash") === observation3.currentInputHashes[item.event.subject]);
36968
37069
  const preservedIds = new Set(preserved.map((item) => item.event.eventId));
36969
37070
  const receipt2 = {
36970
37071
  schemaVersion: 1,
@@ -36974,18 +37075,18 @@ function admitStoppedMission(input2, projectedHistory = input2.stream.events) {
36974
37075
  priorJournalLastSeq: stream2.lastSeq,
36975
37076
  requestHash: canonicalJsonHash(request),
36976
37077
  request,
36977
- observation: observation2,
37078
+ observation: observation3,
36978
37079
  preservedCompletionEventIds: [...preservedIds],
36979
37080
  invalidatedCompletionEventIds: existing.filter((item) => !preservedIds.has(item.event.eventId)).map((item) => item.event.eventId),
36980
37081
  inadmissibleCompletionEventIds: inadmissible,
36981
37082
  roundCorrections,
36982
37083
  consumedRounds,
36983
37084
  remainingRounds: Math.max(0, reviewInput.maxRounds - consumedRounds),
36984
- ...!replacement && disposition.kind !== "review-provenance" ? {} : {
37085
+ ...!replacement && !targetedContext && disposition.kind !== "review-provenance" ? {} : {
36985
37086
  consumedCorrectionBatches,
36986
37087
  remainingCorrectionBatches: 2 - consumedCorrectionBatches
36987
37088
  },
36988
- 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"
37089
+ nextAction: replacement || targetedContext || 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"
36989
37090
  };
36990
37091
  if (new TextEncoder().encode(canonicalJson(receipt2)).length > 16384) {
36991
37092
  return refuse2("recovery-receipt-too-large", "Narrow the recovery scope to the supported bounded incident");
@@ -37012,7 +37113,7 @@ function recoveryRequest(value) {
37012
37113
  if (disposition["kind"] === "command-correction") {
37013
37114
  return exactKeys2(disposition, ["kind", "pairs", "resolutionArtifact"]) && isCommandEvidenceCorrections(disposition["pairs"]) && artifact(disposition["resolutionArtifact"]);
37014
37115
  }
37015
- return disposition["kind"] === "controller-defect" ? exactKeys2(disposition, ["kind", "defect"]) && ["partial-fanout-round", "stale-input-dispatch", "opaque-native-context"].includes(String(disposition["defect"])) : (disposition["kind"] === "review-blocker" || disposition["kind"] === "review-provenance") && exactKeys2(disposition, ["kind", "completionEventIds", "resolutionArtifact"]) && Array.isArray(disposition["completionEventIds"]) && disposition["completionEventIds"].length <= 64 && disposition["completionEventIds"].every((item) => typeof item === "string") && artifact(disposition["resolutionArtifact"]);
37116
+ return disposition["kind"] === "controller-defect" ? exactKeys2(disposition, ["kind", "defect"]) && ["partial-fanout-round", "stale-input-dispatch", "opaque-native-context", "targeted-review-context"].includes(String(disposition["defect"])) : (disposition["kind"] === "review-blocker" || disposition["kind"] === "review-provenance") && exactKeys2(disposition, ["kind", "completionEventIds", "resolutionArtifact"]) && Array.isArray(disposition["completionEventIds"]) && disposition["completionEventIds"].length <= 64 && disposition["completionEventIds"].every((item) => typeof item === "string") && artifact(disposition["resolutionArtifact"]);
37016
37117
  }
37017
37118
  function reviewBinding(value) {
37018
37119
  if (typeof value !== "object" || value === null || Array.isArray(value))
@@ -37062,11 +37163,11 @@ function validateRecoveries(events) {
37062
37163
  if (event.kind !== "mission.recovered")
37063
37164
  continue;
37064
37165
  const request = field4(event, "request");
37065
- const observation2 = field4(event, "observation");
37066
- if (event.source !== "void-harness:mission.recover" || !recoveryRequest(request) || !recoveryObservation(observation2))
37166
+ const observation3 = field4(event, "observation");
37167
+ if (event.source !== "void-harness:mission.recover" || !recoveryRequest(request) || !recoveryObservation(observation3))
37067
37168
  return void 0;
37068
37169
  const prefix = events.slice(0, index);
37069
- const decision = admitStoppedMission({ stream: streamFrom(prefix), request, observation: observation2 }, projectRecoveries(prefix, validated));
37170
+ const decision = admitStoppedMission({ stream: streamFrom(prefix), request, observation: observation3 }, projectRecoveries(prefix, validated));
37070
37171
  if (decision.kind !== "recover" || canonicalJsonHash(decision.receipt) !== canonicalJsonHash(event.payload))
37071
37172
  return void 0;
37072
37173
  validated.push({ event, receipt: decision.receipt });
@@ -37350,18 +37451,18 @@ function label3(value, min, max) {
37350
37451
  }
37351
37452
  return true;
37352
37453
  }
37353
- function stringList2(value, field9) {
37454
+ function stringList2(value, field11) {
37354
37455
  if (value === void 0)
37355
37456
  return Object.freeze([]);
37356
37457
  if (!Array.isArray(value) || value.length > MAX_POLICY_SIGNALS) {
37357
- return `${field9} must be an array of at most ${MAX_POLICY_SIGNALS} signals`;
37458
+ return `${field11} must be an array of at most ${MAX_POLICY_SIGNALS} signals`;
37358
37459
  }
37359
37460
  if (!value.every((item) => label3(item, 1, 64) && SIGNAL_ID.test(item))) {
37360
- return `${field9} contains an invalid signal`;
37461
+ return `${field11} contains an invalid signal`;
37361
37462
  }
37362
37463
  const values = [...value].sort();
37363
37464
  if (new Set(values).size !== values.length) {
37364
- return `${field9} contains duplicate signals`;
37465
+ return `${field11} contains duplicate signals`;
37365
37466
  }
37366
37467
  return Object.freeze(values);
37367
37468
  }
@@ -37465,9 +37566,9 @@ function parseWaiver(value, index) {
37465
37566
  expiresAt: raw["expiresAt"]
37466
37567
  });
37467
37568
  }
37468
- function parseItems(value, maximum, field9, parser) {
37569
+ function parseItems(value, maximum, field11, parser) {
37469
37570
  if (!Array.isArray(value) || value.length === 0 || value.length > maximum) {
37470
- return `${field9} must contain 1 to ${maximum} entries`;
37571
+ return `${field11} must contain 1 to ${maximum} entries`;
37471
37572
  }
37472
37573
  const parsed = [];
37473
37574
  for (const [index, item] of value.entries()) {
@@ -37864,12 +37965,12 @@ var MAX_RISK_STACK_ITEMS = 64;
37864
37965
  function utf8Bytes3(value) {
37865
37966
  return new TextEncoder().encode(value).byteLength;
37866
37967
  }
37867
- function assertBoundedList(values, maximum, field9) {
37968
+ function assertBoundedList(values, maximum, field11) {
37868
37969
  if (values.length > maximum) {
37869
- throw new Error(`RISK_INPUT_TOO_LARGE: ${field9} exceeds ${maximum} entries`);
37970
+ throw new Error(`RISK_INPUT_TOO_LARGE: ${field11} exceeds ${maximum} entries`);
37870
37971
  }
37871
37972
  if (values.some((value) => utf8Bytes3(value) > 512)) {
37872
- throw new Error(`RISK_INPUT_TOO_LARGE: ${field9} contains an entry over 512 bytes`);
37973
+ throw new Error(`RISK_INPUT_TOO_LARGE: ${field11} contains an entry over 512 bytes`);
37873
37974
  }
37874
37975
  }
37875
37976
  function assertBounded(input2) {
@@ -38469,9 +38570,9 @@ function bounded(value, minimum, maximum) {
38469
38570
  }
38470
38571
  return true;
38471
38572
  }
38472
- function normalizeList(values, maximum, field9) {
38573
+ function normalizeList(values, maximum, field11) {
38473
38574
  if (values.length > maximum || values.some((value) => !bounded(value, 1, 512))) {
38474
- throw new Error(`MISSION_INPUT_INVALID: ${field9} is not bounded`);
38575
+ throw new Error(`MISSION_INPUT_INVALID: ${field11} is not bounded`);
38475
38576
  }
38476
38577
  return Object.freeze([...new Set(values)].sort());
38477
38578
  }
@@ -38884,17 +38985,17 @@ function recoveredPreparationTargets(events) {
38884
38985
  if (recovery === void 0)
38885
38986
  return void 0;
38886
38987
  const payload = record15(recovery.payload);
38887
- const observation2 = record15(payload?.["observation"] ?? null);
38988
+ const observation3 = record15(payload?.["observation"] ?? null);
38888
38989
  const request = record15(payload?.["request"] ?? null);
38889
38990
  const disposition = record15(request?.["disposition"] ?? null);
38890
38991
  const ids = disposition?.["completionEventIds"];
38891
- if (observation2?.["stage"] !== "pre-implementation" || !["review-blocker", "preparation-invocation"].includes(String(disposition?.["kind"])) || !Array.isArray(ids))
38992
+ if (observation3?.["stage"] !== "pre-implementation" || !["review-blocker", "preparation-invocation"].includes(String(disposition?.["kind"])) || !Array.isArray(ids))
38892
38993
  return void 0;
38893
38994
  return {
38894
38995
  recoverySeq: recovery.seq,
38895
38996
  replacement: disposition?.["kind"] === "preparation-invocation",
38896
- inputHashes: record15(observation2["currentInputHashes"] ?? {}) ?? {},
38897
- contractVersions: record15(observation2["contractVersions"] ?? {}) ?? {},
38997
+ inputHashes: record15(observation3["currentInputHashes"] ?? {}) ?? {},
38998
+ contractVersions: record15(observation3["contractVersions"] ?? {}) ?? {},
38898
38999
  specialistIds: events.filter((item) => item.kind === "specialist.completed" && ids.includes(item.eventId)).map((item) => item.subject)
38899
39000
  };
38900
39001
  }
@@ -38914,10 +39015,10 @@ function pendingRecoveredCorrectionFindingIds(events) {
38914
39015
  if (recovery === void 0 || events.some((event) => event.seq > recovery.seq && event.kind === "lead-writer.completed"))
38915
39016
  return [];
38916
39017
  const payload = record15(recovery.payload);
38917
- const observation2 = record15(payload?.["observation"] ?? null);
39018
+ const observation3 = record15(payload?.["observation"] ?? null);
38918
39019
  const invalidated = payload?.["invalidatedCompletionEventIds"];
38919
39020
  const remaining = payload?.["remainingRounds"];
38920
- if (payload?.["nextAction"] !== "correction" || observation2?.["stage"] !== "post-implementation" || typeof remaining !== "number" || remaining < 1 || !Array.isArray(invalidated))
39021
+ if (payload?.["nextAction"] !== "correction" || observation3?.["stage"] !== "post-implementation" || typeof remaining !== "number" || remaining < 1 || !Array.isArray(invalidated))
38921
39022
  return [];
38922
39023
  return [...new Set(events.flatMap((event) => {
38923
39024
  if (event.kind !== "specialist.completed" || event.seq >= recovery.seq || !invalidated.includes(event.eventId) || lifecycleField(event, "stage") !== "post-implementation")
@@ -38991,6 +39092,7 @@ function orchestrateMissionTeam(originalInput) {
38991
39092
  contractVersions: contractVersions(input2.plan),
38992
39093
  currentInputHashes: input2.currentInputHashesByStage["pre-implementation"],
38993
39094
  maxRounds: input2.maxReviewRounds,
39095
+ validProofIds: freshReviewProofIds(input2.stream.events, input2.evidenceContext),
38994
39096
  evidenceObligations: {
38995
39097
  ...obligations,
38996
39098
  blockingObligationIds: obligations.blockingObligationIds.filter((id3) => preparationObligationIds.has(id3))
@@ -39106,12 +39208,7 @@ function orchestrateMissionTeam(originalInput) {
39106
39208
  ...start.boundedReview ? BOUNDED_REVIEW_BUDGET : { maxRounds: input2.maxReviewRounds },
39107
39209
  // Pending proofs are handled by obligationStop; they must not mask failed reviews.
39108
39210
  evidenceObligations: { ...obligations, blockingObligationIds: [] },
39109
- validProofIds: input2.stream.events.flatMap((event) => {
39110
- if (event.kind !== "evidence.recorded")
39111
- return [];
39112
- const parsed = parseEvidence(lifecycleField(event, "evidence"));
39113
- 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] : [];
39114
- }),
39211
+ validProofIds: freshReviewProofIds(input2.stream.events, input2.evidenceContext),
39115
39212
  ...migration === void 0 ? {} : { contractMigration: {
39116
39213
  specialistId: migration.receipt.specialistId,
39117
39214
  afterSeq: migration.seq,
@@ -40272,9 +40369,9 @@ var LOGICAL = /^[A-Za-z0-9._~:/-]{1,256}$/;
40272
40369
  function isGraphRelationKind(value) {
40273
40370
  return SEGMENT2.test(value) || value === "decided_by" || value === "constrained_by" || value === "verified_by";
40274
40371
  }
40275
- function segment2(value, field9) {
40372
+ function segment2(value, field11) {
40276
40373
  if (!SEGMENT2.test(value)) {
40277
- throw new Error(`GRAPH_ID_INVALID: ${field9} must be a lower-case namespace segment`);
40374
+ throw new Error(`GRAPH_ID_INVALID: ${field11} must be a lower-case namespace segment`);
40278
40375
  }
40279
40376
  return value;
40280
40377
  }
@@ -42588,8 +42685,11 @@ var manifestSchema = external_exports.object({ hooks: external_exports.record(ex
42588
42685
  matcher: external_exports.string().max(500).optional(),
42589
42686
  hooks: external_exports.array(external_exports.object({ type: external_exports.string(), command: external_exports.string().max(2e3) })).max(100)
42590
42687
  })).max(100)) });
42688
+ function hookRunnerCommand(wrapper) {
42689
+ return /^\s*(?:exec "\$NODE_BIN"|node) "(?:\$HOOK_DIR\/_void-hook\.mjs|\$RUNNER)" ((?:enforce|lifecycle) [a-z-]+|activation|outcome)(?:\s|$)/m.exec(wrapper)?.[1];
42690
+ }
42591
42691
  function hookWiring(name, wrapper, manifests) {
42592
- const runner2 = /^\s*(?:exec "\$NODE_BIN"|node) "(?:\$HOOK_DIR\/_void-hook\.mjs|\$RUNNER)" ((?:enforce|lifecycle) [a-z-]+|activation|outcome)(?:\s|$)/m.exec(wrapper)?.[1];
42692
+ const runner2 = hookRunnerCommand(wrapper);
42593
42693
  return manifests.flatMap(({ runtime: runtime2, value }) => Object.entries(manifestSchema.parse(value).hooks).flatMap(([event, groups]) => groups.filter((group) => group.hooks.some((hook) => {
42594
42694
  if (hook.type !== "command") return false;
42595
42695
  const nodeCall = /^node "\$\{(?:CLAUDE_PLUGIN_ROOT|VOID_HOOKS_DIR)\}\/(?:hooks\/)?_void-hook\.mjs" ([a-z-]+(?: [a-z-]+)*)$/.exec(hook.command)?.[1];
@@ -42598,7 +42698,7 @@ function hookWiring(name, wrapper, manifests) {
42598
42698
  })).map((group) => ({ name, runtime: runtime2, trigger: `${event} (${group.matcher ?? "*"})` }))));
42599
42699
  }
42600
42700
  async function loadCatalog(sourceRoot) {
42601
- const core = await findCoreSource();
42701
+ const core = sourceRoot ?? await findCoreSource();
42602
42702
  const input2 = JSON.parse(await requireData(core, "data/model.json", 4 * 1024 * 1024));
42603
42703
  const specialistDirectory = await lstat(join(core, "specialists"));
42604
42704
  if (!specialistDirectory.isDirectory() || specialistDirectory.isSymbolicLink()) throw new Error("SPECIALIST_SOURCE_INVALID");
@@ -43166,8 +43266,8 @@ init_esm_shims();
43166
43266
  function remedyPrefix(roots) {
43167
43267
  return roots.workRoot === roots.installRoot ? "" : `in ${roots.installRoot}: `;
43168
43268
  }
43169
- function installedPath(roots, relative30) {
43170
- return roots.workRoot === roots.installRoot ? relative30 : join(roots.installRoot, relative30);
43269
+ function installedPath(roots, relative31) {
43270
+ return roots.workRoot === roots.installRoot ? relative31 : join(roots.installRoot, relative31);
43171
43271
  }
43172
43272
 
43173
43273
  // src/lib/cheatsheet/render.ts
@@ -43545,8 +43645,8 @@ function keptTrackedCandidates() {
43545
43645
  }
43546
43646
  var FIX = "a project rule wins over the managed block; run git check-ignore -v <path> to see which, then narrow it so these paths stay visible and git add them";
43547
43647
  function judgeKeptTracked(observations) {
43548
- const reportable = observations.filter((observation2) => observation2.present);
43549
- const hidden = reportable.filter((observation2) => observation2.ignored === true).map((observation2) => `${observation2.path} (${observation2.rule ?? "rule unknown"})`).sort();
43648
+ const reportable = observations.filter((observation3) => observation3.present);
43649
+ const hidden = reportable.filter((observation3) => observation3.ignored === true).map((observation3) => `${observation3.path} (${observation3.rule ?? "rule unknown"})`).sort();
43550
43650
  if (hidden.length > 0) {
43551
43651
  return {
43552
43652
  name: CHECK_NAME,
@@ -43556,7 +43656,7 @@ function judgeKeptTracked(observations) {
43556
43656
  fix: FIX
43557
43657
  };
43558
43658
  }
43559
- const unmeasured = reportable.filter((observation2) => observation2.ignored === void 0).map((observation2) => observation2.path).sort();
43659
+ const unmeasured = reportable.filter((observation3) => observation3.ignored === void 0).map((observation3) => observation3.path).sort();
43560
43660
  if (unmeasured.length > 0) {
43561
43661
  return {
43562
43662
  name: CHECK_NAME,
@@ -47574,12 +47674,12 @@ init_esm_shims();
47574
47674
 
47575
47675
  // src/lib/autopilot/preflight.ts
47576
47676
  init_esm_shims();
47577
- function malformedProgram(observation2) {
47578
- const program = observation2.program;
47677
+ function malformedProgram(observation3) {
47678
+ const program = observation3.program;
47579
47679
  return program !== void 0 && "malformed" in program ? program.malformed : void 0;
47580
47680
  }
47581
- function parsedProgram(observation2) {
47582
- const program = observation2.program;
47681
+ function parsedProgram(observation3) {
47682
+ const program = observation3.program;
47583
47683
  return program === void 0 || "malformed" in program ? void 0 : program;
47584
47684
  }
47585
47685
  var RUNTIME_ADAPTERS = ["claude", "codex"];
@@ -47595,13 +47695,13 @@ function unknown2(name, message2, fix) {
47595
47695
  function unprobed(name, message2) {
47596
47696
  return { name, ok: false, status: "unprobed", message: message2 };
47597
47697
  }
47598
- function programCheck(observation2) {
47698
+ function programCheck(observation3) {
47599
47699
  const name = "autopilot program";
47600
- const broken = malformedProgram(observation2);
47700
+ const broken = malformedProgram(observation3);
47601
47701
  if (broken !== void 0) {
47602
47702
  return fail2(name, `.void/program.md could not be parsed: ${broken.problem}`, broken.fix);
47603
47703
  }
47604
- const program = parsedProgram(observation2);
47704
+ const program = parsedProgram(observation3);
47605
47705
  if (program === void 0) {
47606
47706
  return unknown2(
47607
47707
  name,
@@ -47634,10 +47734,10 @@ function programCheck(observation2) {
47634
47734
  }
47635
47735
  var UNPARSED = "not judged: .void/program.md could not be parsed";
47636
47736
  var UNPARSED_FIX = "fix the frontmatter reported by the program check above, then run doctor again";
47637
- function mergeModeCheck(observation2) {
47737
+ function mergeModeCheck(observation3) {
47638
47738
  const name = "autopilot merge";
47639
- if (malformedProgram(observation2) !== void 0) return unknown2(name, UNPARSED, UNPARSED_FIX);
47640
- const block2 = parsedProgram(observation2)?.autopilot;
47739
+ if (malformedProgram(observation3) !== void 0) return unknown2(name, UNPARSED, UNPARSED_FIX);
47740
+ const block2 = parsedProgram(observation3)?.autopilot;
47641
47741
  const gate = block2?.legacyMergeGate;
47642
47742
  if (gate !== void 0) {
47643
47743
  return fail2(
@@ -47653,10 +47753,10 @@ function mergeModeCheck(observation2) {
47653
47753
  `the loop merges into ${base} on a clean local verdict, never into ${deploying}; \`${PRODUCT_COMMAND} autopilot merges --by-human\` hands every reviewed pull request to a person`
47654
47754
  );
47655
47755
  }
47656
- function verifyCommandsCheck(observation2) {
47756
+ function verifyCommandsCheck(observation3) {
47657
47757
  const name = "autopilot verify";
47658
- if (malformedProgram(observation2) !== void 0) return unknown2(name, UNPARSED, UNPARSED_FIX);
47659
- const commands = parsedProgram(observation2)?.autopilot?.verifyCommands ?? [];
47758
+ if (malformedProgram(observation3) !== void 0) return unknown2(name, UNPARSED, UNPARSED_FIX);
47759
+ const commands = parsedProgram(observation3)?.autopilot?.verifyCommands ?? [];
47660
47760
  if (commands.length === 0) {
47661
47761
  return fail2(
47662
47762
  name,
@@ -47676,9 +47776,9 @@ function verifyCommandsCheck(observation2) {
47676
47776
  }
47677
47777
  return pass(name, `${commands.length} verify command(s)`);
47678
47778
  }
47679
- function adapterCheck(observation2) {
47779
+ function adapterCheck(observation3) {
47680
47780
  const name = "autopilot runtime";
47681
- const usable = observation2.adapters.filter((adapter) => RUNTIME_ADAPTERS.includes(adapter));
47781
+ const usable = observation3.adapters.filter((adapter) => RUNTIME_ADAPTERS.includes(adapter));
47682
47782
  if (usable.length === 0) {
47683
47783
  return fail2(
47684
47784
  name,
@@ -47688,24 +47788,24 @@ function adapterCheck(observation2) {
47688
47788
  }
47689
47789
  return pass(name, `${usable.join(", ")} adapter(s)`);
47690
47790
  }
47691
- function connectorCheck(observation2) {
47791
+ function connectorCheck(observation3) {
47692
47792
  const name = "autopilot tracker";
47693
47793
  {
47694
47794
  return unprobed(name, "not probed here; autopilot proves the connector at preflight, before it claims a lease");
47695
47795
  }
47696
47796
  }
47697
- function worktreeCheck(observation2) {
47797
+ function worktreeCheck(observation3) {
47698
47798
  const name = "autopilot worktrees";
47699
- if (observation2.worktreesUsable === null) {
47799
+ if (observation3.worktreesUsable === null) {
47700
47800
  return unknown2(name, "worktree support could not be determined", "run this inside the git repository autopilot would work in");
47701
47801
  }
47702
- return observation2.worktreesUsable ? pass(name, "worktrees usable") : fail2(
47802
+ return observation3.worktreesUsable ? pass(name, "worktrees usable") : fail2(
47703
47803
  name,
47704
47804
  "worktrees cannot be created here, and a worker never works in the main checkout",
47705
47805
  "run autopilot from a git repository where `git worktree add` succeeds"
47706
47806
  );
47707
47807
  }
47708
- function protectionCheck(observation2) {
47808
+ function protectionCheck(observation3) {
47709
47809
  const name = "autopilot base";
47710
47810
  {
47711
47811
  return unprobed(
@@ -47714,14 +47814,14 @@ function protectionCheck(observation2) {
47714
47814
  );
47715
47815
  }
47716
47816
  }
47717
- function autopilotPreflight(observation2) {
47817
+ function autopilotPreflight(observation3) {
47718
47818
  return Object.freeze([
47719
- programCheck(observation2),
47720
- mergeModeCheck(observation2),
47721
- verifyCommandsCheck(observation2),
47722
- adapterCheck(observation2),
47819
+ programCheck(observation3),
47820
+ mergeModeCheck(observation3),
47821
+ verifyCommandsCheck(observation3),
47822
+ adapterCheck(observation3),
47723
47823
  connectorCheck(),
47724
- worktreeCheck(observation2),
47824
+ worktreeCheck(observation3),
47725
47825
  protectionCheck()
47726
47826
  ]);
47727
47827
  }
@@ -47796,57 +47896,57 @@ function frontmatterOf(text7) {
47796
47896
  }
47797
47897
  return match[1];
47798
47898
  }
47799
- function record19(value, field9) {
47899
+ function record19(value, field11) {
47800
47900
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
47801
47901
  invalid8(
47802
- `the program descriptor has no usable \`${field9}\` block`,
47803
- `\`${field9}\` is ${Array.isArray(value) ? "a list" : String(value)}, not a mapping`,
47804
- `declare \`${field9}:\` as a mapping of its documented fields`
47902
+ `the program descriptor has no usable \`${field11}\` block`,
47903
+ `\`${field11}\` is ${Array.isArray(value) ? "a list" : String(value)}, not a mapping`,
47904
+ `declare \`${field11}:\` as a mapping of its documented fields`
47805
47905
  );
47806
47906
  }
47807
47907
  return value;
47808
47908
  }
47809
- function requiredString(source2, field9, context2) {
47810
- const value = source2[field9];
47909
+ function requiredString(source2, field11, context2) {
47910
+ const value = source2[field11];
47811
47911
  if (typeof value !== "string" || value.trim().length === 0) {
47812
47912
  invalid8(
47813
- `the program descriptor is missing \`${context2}.${field9}\``,
47814
- value === void 0 ? `\`${field9}\` is absent` : `\`${field9}\` is not a non-empty string`,
47815
- `set \`${field9}\` in the \`${context2}\` block to the value it names`
47913
+ `the program descriptor is missing \`${context2}.${field11}\``,
47914
+ value === void 0 ? `\`${field11}\` is absent` : `\`${field11}\` is not a non-empty string`,
47915
+ `set \`${field11}\` in the \`${context2}\` block to the value it names`
47816
47916
  );
47817
47917
  }
47818
47918
  return value;
47819
47919
  }
47820
- function nonEmptyStringList(value, field9) {
47920
+ function nonEmptyStringList(value, field11) {
47821
47921
  if (!Array.isArray(value) || value.length === 0 || value.some((entry) => typeof entry !== "string" || entry.trim().length === 0)) {
47822
47922
  invalid8(
47823
- `the program descriptor has no usable \`${field9}\``,
47824
- `\`${field9}\` must be a non-empty list of non-empty strings`,
47825
- `declare \`${field9}\` as a YAML list naming the provider values actually used`
47923
+ `the program descriptor has no usable \`${field11}\``,
47924
+ `\`${field11}\` must be a non-empty list of non-empty strings`,
47925
+ `declare \`${field11}\` as a YAML list naming the provider values actually used`
47826
47926
  );
47827
47927
  }
47828
47928
  return value;
47829
47929
  }
47830
- function confinedPath(value, field9) {
47930
+ function confinedPath(value, field11) {
47831
47931
  if (isAbsolute(value) || value.split(/[\\/]/).includes("..")) {
47832
47932
  invalid8(
47833
- `the program descriptor \`${field9}\` leaves the repository`,
47933
+ `the program descriptor \`${field11}\` leaves the repository`,
47834
47934
  `\`${value}\` is absolute or walks up out of the project root`,
47835
- `set \`${field9}\` to a path relative to the repository root, without \`..\``
47935
+ `set \`${field11}\` to a path relative to the repository root, without \`..\``
47836
47936
  );
47837
47937
  }
47838
47938
  return value;
47839
47939
  }
47840
- function pathList2(value, field9) {
47940
+ function pathList2(value, field11) {
47841
47941
  if (value === void 0) return [];
47842
47942
  if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string" || entry.trim().length === 0)) {
47843
47943
  invalid8(
47844
- `the program descriptor \`${field9}\` is not a list of paths`,
47845
- `\`${field9}\` must be a list of non-empty strings`,
47846
- `declare \`${field9}\` as a YAML list of repo-relative path patterns`
47944
+ `the program descriptor \`${field11}\` is not a list of paths`,
47945
+ `\`${field11}\` must be a list of non-empty strings`,
47946
+ `declare \`${field11}\` as a YAML list of repo-relative path patterns`
47847
47947
  );
47848
47948
  }
47849
- return value.map((entry) => confinedPath(entry, field9));
47949
+ return value.map((entry) => confinedPath(entry, field11));
47850
47950
  }
47851
47951
  function verifyCommands(value) {
47852
47952
  if (value === void 0) return [];
@@ -48481,37 +48581,37 @@ function settledRenames(resolution) {
48481
48581
  if (settled2.length === 0) return "";
48482
48582
  return `; ${String(settled2.length)} settled rename(s): ${settled2.map(withSuccessor).join(", ")}`;
48483
48583
  }
48484
- function evidence(observation2) {
48485
- const { liveness } = observation2;
48584
+ function evidence(observation3) {
48585
+ const { liveness } = observation3;
48486
48586
  const unseen = liveness.unobservable.map(
48487
48587
  ({ source: source2, toolCalls }) => `skill usage not observable for ${source2} (${toolCalls} tool calls); activation count unknown`
48488
48588
  ).join("; ");
48489
48589
  if (liveness.missions === 0 && unseen !== "") {
48490
- return `${observation2.installedSkills} skill(s) installed; ${unseen}`;
48590
+ return `${observation3.installedSkills} skill(s) installed; ${unseen}`;
48491
48591
  }
48492
48592
  if (liveness.missions === 0) {
48493
- return `${observation2.installedSkills} skill(s) installed, no working mission recorded yet`;
48593
+ return `${observation3.installedSkills} skill(s) installed, no working mission recorded yet`;
48494
48594
  }
48495
- return `${observation2.installedSkills} skill(s) installed, ${liveness.skillCalls} activation(s) across ${liveness.toolCalls} tool calls (${ratio2(liveness)}) over ${liveness.missions} observable Claude working mission(s)` + (unseen === "" ? "" : `; ${unseen}`);
48595
+ return `${observation3.installedSkills} skill(s) installed, ${liveness.skillCalls} activation(s) across ${liveness.toolCalls} tool calls (${ratio2(liveness)}) over ${liveness.missions} observable Claude working mission(s)` + (unseen === "" ? "" : `; ${unseen}`);
48496
48596
  }
48497
- function judgeInvocation(observation2) {
48597
+ function judgeInvocation(observation3) {
48498
48598
  const faults = [];
48499
- if (!observation2.resolution.ok) {
48599
+ if (!observation3.resolution.ok) {
48500
48600
  faults.push(
48501
- `${observation2.resolution.unresolved.length} retired name(s) recorded: ` + observation2.resolution.unresolved.map(withSuccessor).join(", ")
48601
+ `${observation3.resolution.unresolved.length} retired name(s) recorded: ` + observation3.resolution.unresolved.map(withSuccessor).join(", ")
48502
48602
  );
48503
48603
  }
48504
- if (!observation2.liveness.ok) {
48604
+ if (!observation3.liveness.ok) {
48505
48605
  faults.push(
48506
- `no skill fired across ${observation2.liveness.missions} working mission(s) and ${observation2.liveness.toolCalls} tool calls (runtime:claude)`
48606
+ `no skill fired across ${observation3.liveness.missions} working mission(s) and ${observation3.liveness.toolCalls} tool calls (runtime:claude)`
48507
48607
  );
48508
48608
  }
48509
48609
  if (faults.length === 0) {
48510
48610
  return {
48511
48611
  name: NAME3,
48512
- ok: observation2.liveness.unobservable.length === 0,
48513
- status: observation2.liveness.unobservable.length === 0 ? "pass" : "unknown",
48514
- message: `${evidence(observation2)}${settledRenames(observation2.resolution)}`
48612
+ ok: observation3.liveness.unobservable.length === 0,
48613
+ status: observation3.liveness.unobservable.length === 0 ? "pass" : "unknown",
48614
+ message: `${evidence(observation3)}${settledRenames(observation3.resolution)}`
48515
48615
  };
48516
48616
  }
48517
48617
  return {
@@ -48520,11 +48620,11 @@ function judgeInvocation(observation2) {
48520
48620
  status: "fail",
48521
48621
  // Both faults, never the first alone: they have different causes, and fixing
48522
48622
  // one would otherwise reveal the other only on the next run.
48523
- message: `${faults.join("; ")}; ${evidence(observation2)}`,
48623
+ message: `${faults.join("; ")}; ${evidence(observation3)}`,
48524
48624
  // Never "reinstall": the file is not missing, the name moved. What the reader
48525
48625
  // has to change is whatever still calls the old name -- a saved command, a
48526
48626
  // habit, another skill's text.
48527
- fix: !observation2.resolution.ok ? "invoke each successor named above instead, and update whatever still calls the old name" : "inspect the Claude Skill invocation path and activation collector for the silent missions"
48627
+ fix: !observation3.resolution.ok ? "invoke each successor named above instead, and update whatever still calls the old name" : "inspect the Claude Skill invocation path and activation collector for the silent missions"
48528
48628
  };
48529
48629
  }
48530
48630
 
@@ -48553,9 +48653,9 @@ var CHECK_NAME2 = "void observed";
48553
48653
  var FIX2 = `${PRODUCT_COMMAND} update \u2014 it moves observed state under .void/machine/, which the managed block ignores; a path that must stay where it is needs its own .gitignore line`;
48554
48654
  function judgeObservedIgnore(observations) {
48555
48655
  const reportable = observations.filter(
48556
- (observation2) => observation2.present && !isDeliberatelyTracked(observation2.path)
48656
+ (observation3) => observation3.present && !isDeliberatelyTracked(observation3.path)
48557
48657
  );
48558
- const leaking = reportable.filter((observation2) => observation2.ignored === false).map((observation2) => observation2.path).sort();
48658
+ const leaking = reportable.filter((observation3) => observation3.ignored === false).map((observation3) => observation3.path).sort();
48559
48659
  if (leaking.length > 0) {
48560
48660
  return {
48561
48661
  name: CHECK_NAME2,
@@ -48565,7 +48665,7 @@ function judgeObservedIgnore(observations) {
48565
48665
  fix: FIX2
48566
48666
  };
48567
48667
  }
48568
- const unmeasured = reportable.filter((observation2) => observation2.ignored === void 0).map((observation2) => observation2.path).sort();
48668
+ const unmeasured = reportable.filter((observation3) => observation3.ignored === void 0).map((observation3) => observation3.path).sort();
48569
48669
  if (unmeasured.length > 0) {
48570
48670
  return {
48571
48671
  name: CHECK_NAME2,
@@ -48653,38 +48753,38 @@ function fail3(name, message2, fix) {
48653
48753
  function unknown3(name, message2, fix) {
48654
48754
  return { name, ok: false, status: "unknown", message: message2, fix };
48655
48755
  }
48656
- function layoutCheck(observation2) {
48756
+ function layoutCheck(observation3) {
48657
48757
  const name = "void layout";
48658
- if (observation2.pending.length === 0) return pass2(name, "observed state is under .void/machine/");
48758
+ if (observation3.pending.length === 0) return pass2(name, "observed state is under .void/machine/");
48659
48759
  return fail3(
48660
48760
  name,
48661
- `${observation2.pending.length} observed path(s) still at the old location: ${observation2.pending.join(", ")}`,
48761
+ `${observation3.pending.length} observed path(s) still at the old location: ${observation3.pending.join(", ")}`,
48662
48762
  `${PRODUCT_COMMAND} update \u2014 it moves them under .void/machine/ and never overwrites`
48663
48763
  );
48664
48764
  }
48665
- function ignoreCheck(observation2) {
48765
+ function ignoreCheck(observation3) {
48666
48766
  const name = "void ignore";
48667
- if (observation2.localIgnored === null) {
48767
+ if (observation3.localIgnored === null) {
48668
48768
  return unknown3(name, "not a git repository, so nothing ignores anything here", "run this inside the repository the project ships from");
48669
48769
  }
48670
- return observation2.localIgnored ? pass2(name, ".void/machine/ is ignored") : fail3(
48770
+ return observation3.localIgnored ? pass2(name, ".void/machine/ is ignored") : fail3(
48671
48771
  name,
48672
48772
  ".void/machine/ is NOT ignored, so telemetry and run journals would be committed",
48673
48773
  `${PRODUCT_COMMAND} update \u2014 it writes the managed block; check no later rule re-includes .void/`
48674
48774
  );
48675
48775
  }
48676
- function trackedCheck(observation2) {
48776
+ function trackedCheck(observation3) {
48677
48777
  const name = "void tracked";
48678
- if (observation2.trackedObserved.length === 0) return pass2(name, "no observed state in the index");
48778
+ if (observation3.trackedObserved.length === 0) return pass2(name, "no observed state in the index");
48679
48779
  return fail3(
48680
48780
  name,
48681
- `git tracks ${observation2.trackedObserved.length} observed path(s): ${observation2.trackedObserved.join(", ")}`,
48682
- `git rm --cached -r ${observation2.trackedObserved.join(" ")} \u2014 the ignore rule cannot untrack what is already in the index`
48781
+ `git tracks ${observation3.trackedObserved.length} observed path(s): ${observation3.trackedObserved.join(", ")}`,
48782
+ `git rm --cached -r ${observation3.trackedObserved.join(" ")} \u2014 the ignore rule cannot untrack what is already in the index`
48683
48783
  );
48684
48784
  }
48685
- function orphanCheck(observation2) {
48785
+ function orphanCheck(observation3) {
48686
48786
  const name = "void orphans";
48687
- const orphans2 = observation2.orphanedAssets;
48787
+ const orphans2 = observation3.orphanedAssets;
48688
48788
  if (orphans2.length === 0) {
48689
48789
  return { name, ok: true, message: "no harness asset on disk that the manifest lost track of" };
48690
48790
  }
@@ -48696,9 +48796,9 @@ function orphanCheck(observation2) {
48696
48796
  fix: "they were edited locally, so update kept them; delete them to stop loading two versions"
48697
48797
  };
48698
48798
  }
48699
- function manifestCheck(observation2) {
48799
+ function manifestCheck(observation3) {
48700
48800
  const name = "void manifest";
48701
- const manifest = observation2.manifest;
48801
+ const manifest = observation3.manifest;
48702
48802
  if (manifest.kind === "absent") {
48703
48803
  return {
48704
48804
  name,
@@ -48727,9 +48827,9 @@ function manifestCheck(observation2) {
48727
48827
  coEdited === 0 ? `assets match manifest ${version3}` : `assets match manifest ${version3}; ${String(coEdited)} co-owned file(s) carry project edits`
48728
48828
  );
48729
48829
  }
48730
- function receiptCheck(observation2) {
48830
+ function receiptCheck(observation3) {
48731
48831
  const name = "void receipt";
48732
- const receipt2 = observation2.receipt;
48832
+ const receipt2 = observation3.receipt;
48733
48833
  if (receipt2.kind === "absent") {
48734
48834
  return {
48735
48835
  name,
@@ -48748,7 +48848,7 @@ function receiptCheck(observation2) {
48748
48848
  if (missingTotal === 0) return pass2(name, `every file receipt ${version3} recorded is on disk`);
48749
48849
  const example2 = receipt2.missing?.[0];
48750
48850
  const shown = example2 === void 0 ? "" : `, for example ${example2}`;
48751
- const manifest = observation2.manifest;
48851
+ const manifest = observation3.manifest;
48752
48852
  const rolledBack = manifest.kind === "present" && manifest.version !== void 0 && manifest.version !== version3;
48753
48853
  if (rolledBack) {
48754
48854
  return fail3(
@@ -48759,14 +48859,14 @@ function receiptCheck(observation2) {
48759
48859
  }
48760
48860
  return fail3(name, `receipt ${version3} records ${String(missingTotal)} file(s) that are not on disk${shown}`, fix);
48761
48861
  }
48762
- function derivedCheck(observation2) {
48862
+ function derivedCheck(observation3) {
48763
48863
  const name = "void derived";
48764
- if (observation2.trackedDerivedCount === 0) return pass2(name, "no regenerated content in the index");
48864
+ if (observation3.trackedDerivedCount === 0) return pass2(name, "no regenerated content in the index");
48765
48865
  return {
48766
48866
  name,
48767
48867
  ok: true,
48768
48868
  status: "advisory",
48769
- message: `git tracks ${observation2.trackedDerivedCount} file(s) that \`hydrate\` restores from the manifest`,
48869
+ message: `git tracks ${observation3.trackedDerivedCount} file(s) that \`hydrate\` restores from the manifest`,
48770
48870
  fix: `${PRODUCT_COMMAND} update --untrack-derived (keeps the files on disk, drops them from the index)`
48771
48871
  };
48772
48872
  }
@@ -48784,24 +48884,24 @@ function judgeProjectSkills(ignored) {
48784
48884
  fix
48785
48885
  };
48786
48886
  }
48787
- function judgeLayout(observation2) {
48887
+ function judgeLayout(observation3) {
48788
48888
  return Object.freeze([
48789
- layoutCheck(observation2),
48790
- ignoreCheck(observation2),
48889
+ layoutCheck(observation3),
48890
+ ignoreCheck(observation3),
48791
48891
  // Generalizes the check above from the one declared path to every path the
48792
48892
  // harness can write observed state to, legacy locations included.
48793
- judgeObservedIgnore(observation2.observedPaths),
48893
+ judgeObservedIgnore(observation3.observedPaths),
48794
48894
  // The same question the other way round: a declaration that a path stays
48795
48895
  // TRACKED is no more a proof than one that a path is ignored.
48796
- judgeKeptTracked(observation2.keptTracked),
48797
- orphanCheck(observation2),
48798
- trackedCheck(observation2),
48799
- manifestCheck(observation2),
48896
+ judgeKeptTracked(observation3.keptTracked),
48897
+ orphanCheck(observation3),
48898
+ trackedCheck(observation3),
48899
+ manifestCheck(observation3),
48800
48900
  // After the manifest, deliberately: when the assets were rolled back the
48801
48901
  // manifest reads green, and the reader needs the two lines side by side to
48802
48902
  // see that the green one is answering about the wrong version.
48803
- receiptCheck(observation2),
48804
- derivedCheck(observation2)
48903
+ receiptCheck(observation3),
48904
+ derivedCheck(observation3)
48805
48905
  ]);
48806
48906
  }
48807
48907
 
@@ -50119,9 +50219,9 @@ async function observeLayout(root) {
50119
50219
  const listed = git4(["ls-files", "-z", "--", ".void"]) ?? "";
50120
50220
  const tracked = listed.split("\0").filter((path3) => path3 !== "");
50121
50221
  const trackedObserved = tracked.filter((path3) => {
50122
- const relative30 = path3.startsWith(".void/") ? path3.slice(".void/".length) : path3;
50123
- if (relative30.startsWith(`${VOID_MACHINE_DIR}/`)) return true;
50124
- return isMachineEntry(relative30.split("/")[0] ?? "");
50222
+ const relative31 = path3.startsWith(".void/") ? path3.slice(".void/".length) : path3;
50223
+ if (relative31.startsWith(`${VOID_MACHINE_DIR}/`)) return true;
50224
+ return isMachineEntry(relative31.split("/")[0] ?? "");
50125
50225
  });
50126
50226
  const materialized = git4(["ls-files", "-z", "--", ".void", ".claude", ".agents", ".codex"]) ?? "";
50127
50227
  const trackedDerivedCount = owned === void 0 ? 0 : materialized.split("\0").filter((path3) => path3 !== "" && owned.has(path3.split("\\").join("/"))).length;
@@ -50158,15 +50258,15 @@ function observeOrphanedAssets(root) {
50158
50258
  return [];
50159
50259
  }
50160
50260
  const discovered = [];
50161
- const walk = (relative30) => {
50261
+ const walk = (relative31) => {
50162
50262
  let entries;
50163
50263
  try {
50164
- entries = readdirSync(join(root, relative30));
50264
+ entries = readdirSync(join(root, relative31));
50165
50265
  } catch {
50166
50266
  return;
50167
50267
  }
50168
50268
  for (const entry of entries) {
50169
- const child = `${relative30}/${entry}`;
50269
+ const child = `${relative31}/${entry}`;
50170
50270
  const absolute2 = join(root, child);
50171
50271
  let isDirectory = false;
50172
50272
  try {
@@ -50261,14 +50361,14 @@ function observeIgnoredProjectSkills(root) {
50261
50361
  }
50262
50362
  for (const entry of entries) {
50263
50363
  if (!entry.isDirectory()) continue;
50264
- const relative30 = `${home}/${entry.name}`;
50265
- if ([...owned].some((path3) => path3.startsWith(`${relative30}/`))) continue;
50364
+ const relative31 = `${home}/${entry.name}`;
50365
+ if ([...owned].some((path3) => path3.startsWith(`${relative31}/`))) continue;
50266
50366
  try {
50267
- execFileSync("git", ["check-ignore", "-q", `${relative30}/`], {
50367
+ execFileSync("git", ["check-ignore", "-q", `${relative31}/`], {
50268
50368
  cwd: root,
50269
50369
  stdio: ["ignore", "ignore", "ignore"]
50270
50370
  });
50271
- ignored.push(relative30);
50371
+ ignored.push(relative31);
50272
50372
  } catch {
50273
50373
  }
50274
50374
  }
@@ -51358,32 +51458,32 @@ function observedDone(view, input2) {
51358
51458
  return { transition: next(view, input2.now, "turn-ended", "result-missing", "the agent ended its turn but the delegation-result hook recorded no final message", "send a message asking for the final result: void-machine agents send <runId>") };
51359
51459
  }
51360
51460
  function endedByResult(view, input2) {
51361
- const { observation: observation2, result, now } = input2;
51362
- if (observation2.kind !== "present" || observation2.status === "busy")
51461
+ const { observation: observation3, result, now } = input2;
51462
+ if (observation3.kind !== "present" || observation3.status === "busy")
51363
51463
  return void 0;
51364
- if (observation2.state === "failed" || observation2.state === "stopped")
51464
+ if (observation3.state === "failed" || observation3.state === "stopped")
51365
51465
  return void 0;
51366
51466
  if (result === void 0 || result.recordedAt < view.turnStartedAt || result.pendingWork > 0)
51367
51467
  return void 0;
51368
51468
  if (view.state === "turn-ended")
51369
51469
  return {};
51370
- const question = observation2.state === "blocked";
51470
+ const question = observation3.state === "blocked";
51371
51471
  return { transition: next(view, now, "turn-ended", "turn-ended", question ? "the agent ended its turn with a question; its final message is collected" : "the agent ended its turn and its final message is collected", question ? "answer with void-machine agents send <runId>, or accept the result" : "read it with void-machine agents status <runId>, then accept or send") };
51372
51472
  }
51373
51473
  function observeRun(view, input2) {
51374
- const { observation: observation2, now } = input2;
51375
- if (!isOpen(view.state) || observation2.kind === "unreadable")
51474
+ const { observation: observation3, now } = input2;
51475
+ if (!isOpen(view.state) || observation3.kind === "unreadable")
51376
51476
  return {};
51377
- if (observation2.kind === "absent")
51477
+ if (observation3.kind === "absent")
51378
51478
  return observedAbsent(view, now);
51379
51479
  const ended = endedByResult(view, input2);
51380
51480
  if (ended !== void 0)
51381
51481
  return ended;
51382
- switch (observation2.state) {
51482
+ switch (observation3.state) {
51383
51483
  case "working":
51384
51484
  return view.state === "working" ? {} : { transition: next(view, now, "working", "observed", "the agent is working", "wait with void-machine agents wait <runId>") };
51385
51485
  case "blocked": {
51386
- const waitingFor = observation2.waitingFor ?? "input needed";
51486
+ const waitingFor = observation3.waitingFor ?? "input needed";
51387
51487
  if (view.state === "waiting-human" && view.last.waitingFor === waitingFor)
51388
51488
  return {};
51389
51489
  return { transition: next(view, now, "waiting-human", "observed", `the agent waits for a person: ${waitingFor}`, "decide in the agent session: void-machine agents attach <runId>", waitingFor) };
@@ -51395,7 +51495,7 @@ function observeRun(view, input2) {
51395
51495
  case "stopped":
51396
51496
  return { transition: next(view, now, "stopped", "observed", "the session was stopped", "dispatch a new run if the work is still needed") };
51397
51497
  default: {
51398
- const unknown4 = observation2.state;
51498
+ const unknown4 = observation3.state;
51399
51499
  return unknown4;
51400
51500
  }
51401
51501
  }
@@ -51458,9 +51558,9 @@ function remoteReference(value, depth = 0) {
51458
51558
  }
51459
51559
  if (!isObject3(value))
51460
51560
  return void 0;
51461
- const reference = value["$ref"];
51462
- if (typeof reference === "string" && !reference.startsWith("#")) {
51463
- return `the schema names a $ref outside itself (${reference.slice(0, 100)})`;
51561
+ const reference2 = value["$ref"];
51562
+ if (typeof reference2 === "string" && !reference2.startsWith("#")) {
51563
+ return `the schema names a $ref outside itself (${reference2.slice(0, 100)})`;
51464
51564
  }
51465
51565
  for (const child of Object.values(value)) {
51466
51566
  const found = remoteReference(child, depth + 1);
@@ -54285,8 +54385,8 @@ var localReviewSchema = external_exports.strictObject({
54285
54385
  }
54286
54386
  });
54287
54387
  function describeIssue(issue4) {
54288
- const field9 = issue4.path.length === 0 ? "(root)" : issue4.path.map(String).join(".");
54289
- return `${field9}: ${issue4.message}`;
54388
+ const field11 = issue4.path.length === 0 ? "(root)" : issue4.path.map(String).join(".");
54389
+ return `${field11}: ${issue4.message}`;
54290
54390
  }
54291
54391
  function admit2(what, schema, value) {
54292
54392
  const parsed = schema.safeParse(value);
@@ -54526,13 +54626,10 @@ var TRACKED_TICKETS_MAX = 256;
54526
54626
  var HUMAN_WAIT_LABEL = "void:human-wait";
54527
54627
  var PROTECTED_PATHS_FLOOR = [
54528
54628
  ".github/**",
54529
- "scripts/independent-review-check.mjs",
54530
- "scripts/independent-review-run.mjs",
54531
- // What a judging workflow runs from outside `.github`: the promotion audit
54532
- // runs develop's own copy, void-enforce replays the auto-merge contract and
54629
+ // What a judging workflow runs from outside `.github`: void-enforce
54630
+ // replays the auto-merge contract and
54533
54631
  // the enforcement floor from the pull request, and ci.yml's required verdict
54534
54632
  // is aggregated by verify.mjs.
54535
- "scripts/promotion-authority.mjs",
54536
54633
  "scripts/auto-merge-contract.mjs",
54537
54634
  "scripts/verify.mjs",
54538
54635
  "packages/core/enforce/**",
@@ -54681,8 +54778,8 @@ function admitLoopTracker(value) {
54681
54778
  const parsed = loopTrackerSchema.safeParse(value);
54682
54779
  if (parsed.success) return { ok: true, value: parsed.data };
54683
54780
  const issues = parsed.error.issues.map((issue4) => {
54684
- const field9 = issue4.path.length === 0 ? "(root)" : issue4.path.join(".");
54685
- return `${field9}: ${issue4.message}`;
54781
+ const field11 = issue4.path.length === 0 ? "(root)" : issue4.path.join(".");
54782
+ return `${field11}: ${issue4.message}`;
54686
54783
  }).join("; ");
54687
54784
  return { ok: false, reason: `tracker observation refused: ${issues}` };
54688
54785
  }
@@ -55169,8 +55266,8 @@ var COMMIT_SHA = /^[0-9a-f]{40}$/;
55169
55266
  function blocked(reason2, detail) {
55170
55267
  return { kind: "blocked", reason: reason2, detail };
55171
55268
  }
55172
- function selectBase(observation2) {
55173
- const branches = observation2.branches;
55269
+ function selectBase(observation3) {
55270
+ const branches = observation3.branches;
55174
55271
  if (!Array.isArray(branches) || branches.length === 0) {
55175
55272
  return blocked("no-conventional-base", "the observation lists no branch on the remote");
55176
55273
  }
@@ -55187,7 +55284,7 @@ function selectBase(observation2) {
55187
55284
  }
55188
55285
  names.add(branch.name);
55189
55286
  }
55190
- const requested = observation2.requested;
55287
+ const requested = observation3.requested;
55191
55288
  if (typeof requested !== "string" || requested.trim().length === 0) {
55192
55289
  return blocked(
55193
55290
  "requested-base-missing",
@@ -56155,7 +56252,7 @@ async function inspectMission(root, missionId, context2, options2 = {}) {
56155
56252
  }
56156
56253
  const text7 = await readFile(log, "utf8");
56157
56254
  const stream2 = replayEventLog(text7);
56158
- const quarantineFiles = await quarantineInvalidLines(
56255
+ const quarantineFiles = options2.quarantine === false ? [] : await quarantineInvalidLines(
56159
56256
  run2,
56160
56257
  text7,
56161
56258
  options2.secrets ?? collectKnownSecrets()
@@ -58172,29 +58269,29 @@ init_esm_shims();
58172
58269
  var import_yaml8 = __toESM(require_dist());
58173
58270
  var import_yaml9 = __toESM(require_dist());
58174
58271
  var import_picomatch4 = __toESM(require_picomatch2());
58175
- function invalid9(field9) {
58176
- throw new Error(`invalid declaration field: ${field9}`);
58272
+ function invalid9(field11) {
58273
+ throw new Error(`invalid declaration field: ${field11}`);
58177
58274
  }
58178
- function text4(value, field9, max = 512) {
58275
+ function text4(value, field11, max = 512) {
58179
58276
  if (typeof value !== "string" || value.length === 0 || value.length > max)
58180
- invalid9(field9);
58277
+ invalid9(field11);
58181
58278
  if ([...value].some((c2) => {
58182
58279
  const n = c2.codePointAt(0) ?? 0;
58183
58280
  return n < 32 || n >= 127 && n <= 159;
58184
58281
  }))
58185
- invalid9(field9);
58282
+ invalid9(field11);
58186
58283
  return value;
58187
58284
  }
58188
- function list3(value, field9, optional2 = false) {
58285
+ function list3(value, field11, optional2 = false) {
58189
58286
  if (optional2 && value === void 0) return Object.freeze([]);
58190
- if (!Array.isArray(value) || value.length > 256) invalid9(field9);
58287
+ if (!Array.isArray(value) || value.length > 256) invalid9(field11);
58191
58288
  return Object.freeze(
58192
- [...new Set(value.map((v2) => text4(v2, field9, 1024)))].sort()
58289
+ [...new Set(value.map((v2) => text4(v2, field11, 1024)))].sort()
58193
58290
  );
58194
58291
  }
58195
- function choice(value, field9, choices) {
58196
- const parsed = text4(value, field9, 32);
58197
- if (!choices.includes(parsed)) invalid9(field9);
58292
+ function choice(value, field11, choices) {
58293
+ const parsed = text4(value, field11, 32);
58294
+ if (!choices.includes(parsed)) invalid9(field11);
58198
58295
  return parsed;
58199
58296
  }
58200
58297
  function validateProjectDeclaration(value, kind2) {
@@ -59131,9 +59228,9 @@ function createTypeScriptExtractor(api) {
59131
59228
  function configError(message2) {
59132
59229
  throw new Error(`PROJECT_TYPESCRIPT_CONFIG_INVALID: ${message2}`);
59133
59230
  }
59134
- function jsonRecord2(value, field9) {
59231
+ function jsonRecord2(value, field11) {
59135
59232
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
59136
- return configError(`${field9} must be an object`);
59233
+ return configError(`${field11} must be an object`);
59137
59234
  }
59138
59235
  return value;
59139
59236
  }
@@ -59340,9 +59437,9 @@ function resolveTypeScriptConfigInheritance(api, configs, caseSensitive) {
59340
59437
  function workspaceError(message2) {
59341
59438
  throw new Error(`PROJECT_WORKSPACE_INVALID: ${message2}`);
59342
59439
  }
59343
- function record21(value, field9) {
59440
+ function record21(value, field11) {
59344
59441
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
59345
- return workspaceError(`${field9} must be an object`);
59442
+ return workspaceError(`${field11} must be an object`);
59346
59443
  }
59347
59444
  return value;
59348
59445
  }
@@ -59355,13 +59452,13 @@ function containsControl(value) {
59355
59452
  function dependencyNames(input2) {
59356
59453
  const names = /* @__PURE__ */ new Set();
59357
59454
  const fields = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
59358
- for (const field9 of fields) {
59359
- const value = input2[field9];
59455
+ for (const field11 of fields) {
59456
+ const value = input2[field11];
59360
59457
  if (value === void 0) continue;
59361
- for (const name of Object.keys(record21(value, field9))) {
59458
+ for (const name of Object.keys(record21(value, field11))) {
59362
59459
  if (names.size >= 1e4) workspaceError("dependency declarations exceed their limit");
59363
59460
  if (name.length === 0 || name.length > 214 || containsControl(name)) {
59364
- workspaceError(`${field9} contains an invalid package name`);
59461
+ workspaceError(`${field11} contains an invalid package name`);
59365
59462
  }
59366
59463
  names.add(name);
59367
59464
  }
@@ -59465,8 +59562,8 @@ function workspaceExports(input2, workspacePath) {
59465
59562
  }
59466
59563
  function workspaceEntrypoints(input2, workspacePath, exports) {
59467
59564
  const raw = [];
59468
- for (const field9 of ["source", "main", "module", "types", "typings"]) {
59469
- entrypointStrings(input2[field9], raw);
59565
+ for (const field11 of ["source", "main", "module", "types", "typings"]) {
59566
+ entrypointStrings(input2[field11], raw);
59470
59567
  }
59471
59568
  const exported2 = exports["."] ?? [];
59472
59569
  if (exported2.length === 0 && raw.length === 0) {
@@ -60616,6 +60713,9 @@ function executableCandidates() {
60616
60713
  join(programFiles, "Git", "bin", "git.exe")
60617
60714
  ];
60618
60715
  }
60716
+ if (process.platform === "darwin") {
60717
+ return ["/opt/homebrew/bin/git", "/usr/local/bin/git", "/usr/bin/git", "/bin/git"];
60718
+ }
60619
60719
  return ["/usr/bin/git", "/bin/git", "/usr/local/bin/git", "/opt/homebrew/bin/git"];
60620
60720
  }
60621
60721
  async function trustedGitPath(explicit) {
@@ -63358,15 +63458,15 @@ function ownersOf(snapshot2, id3) {
63358
63458
  function testsFor(snapshot2, id3) {
63359
63459
  return relatedThrough(snapshot2, id3, TEST_KINDS, true, `no test coverage was extracted for ${id3}`);
63360
63460
  }
63361
- function stalenessOf(snapshot2, observation2) {
63362
- if (snapshot2.source.rootHash !== observation2.rootHash) {
63461
+ function stalenessOf(snapshot2, observation22) {
63462
+ if (snapshot2.source.rootHash !== observation22.rootHash) {
63363
63463
  return {
63364
63464
  stale: true,
63365
63465
  fallback: "source",
63366
- reason: `the root hash moved (${snapshot2.source.rootHash} -> ${observation2.rootHash}); read source instead`
63466
+ reason: `the root hash moved (${snapshot2.source.rootHash} -> ${observation22.rootHash}); read source instead`
63367
63467
  };
63368
63468
  }
63369
- if (!observation2.complete) {
63469
+ if (!observation22.complete) {
63370
63470
  return {
63371
63471
  stale: false,
63372
63472
  fallback: "source",
@@ -65943,8 +66043,8 @@ function enclosingProject2(from) {
65943
66043
  }
65944
66044
  }
65945
66045
  function readCheckpointFile(root) {
65946
- for (const relative30 of CHECKPOINT_PATHS) {
65947
- const path3 = join(root, relative30);
66046
+ for (const relative31 of CHECKPOINT_PATHS) {
66047
+ const path3 = join(root, relative31);
65948
66048
  try {
65949
66049
  if (!existsSync(path3)) continue;
65950
66050
  return {
@@ -67162,16 +67262,588 @@ async function pruneMissions(root, olderThanDays, apply, now = /* @__PURE__ */ n
67162
67262
  return candidates;
67163
67263
  }
67164
67264
 
67265
+ // src/commands/mission-usage.ts
67266
+ init_esm_shims();
67267
+
67268
+ // src/lib/runs/usage-sessions.ts
67269
+ init_esm_shims();
67270
+
67271
+ // src/lib/runs/usage-session-contract.ts
67272
+ init_esm_shims();
67273
+ var usageMissionId = external_exports.string().regex(/^mis_[A-Za-z0-9_-]{8,100}$/);
67274
+ var anchorSchema = external_exports.strictObject({
67275
+ seq: external_exports.number().int().nonnegative(),
67276
+ eventId: external_exports.string().regex(/^(?:origin|evt_[A-Za-z0-9_-]{8,100})$/),
67277
+ digest: external_exports.string().regex(/^sha256:[a-f0-9]{64}$/)
67278
+ });
67279
+ var openingSchema = external_exports.strictObject({ targetMissionId: usageMissionId, previous: anchorSchema });
67280
+ var closingSchema2 = openingSchema.extend({ opening: anchorSchema });
67281
+ var usageReferenceSchema = external_exports.strictObject({ sourceMissionId: usageMissionId, opening: anchorSchema });
67282
+ var USAGE_SOURCE = `${PRODUCT_COMMAND}:usage`;
67283
+ var isUsageSource = (source2) => [PRODUCT_COMMAND, ...PRODUCT_IDENTITY.commands.deprecated].some((command2) => source2 === `${command2}:usage`);
67284
+ var MAX_USAGE_LINKS = 32;
67285
+ var usageEventId = (...parts) => `evt_usage_${canonicalJsonHash(parts).slice(7)}`;
67286
+ var sameUsageAnchor = (left, right) => left.seq === right.seq && left.eventId === right.eventId && left.digest === right.digest;
67287
+ function scanUsageSource(events, sourceMissionId) {
67288
+ let prefix = { seq: 0, eventId: "origin", digest: canonicalJsonHash([]) };
67289
+ let active;
67290
+ const intervals = /* @__PURE__ */ new Map();
67291
+ const seen = /* @__PURE__ */ new Set();
67292
+ for (const event of events) {
67293
+ if (event.seq !== prefix.seq + 1 || event.missionId !== sourceMissionId || event.correlationId !== sourceMissionId || seen.has(event.eventId)) {
67294
+ throw new Error("USAGE_SOURCE_INTEGRITY: inconsistent source journal");
67295
+ }
67296
+ seen.add(event.eventId);
67297
+ const next2 = {
67298
+ seq: event.seq,
67299
+ eventId: event.eventId,
67300
+ digest: canonicalJsonHash([prefix.digest, event])
67301
+ };
67302
+ if (event.kind === "usage.session.opened" || event.kind === "usage.session.closed") {
67303
+ const parsed = (event.kind === "usage.session.opened" ? openingSchema : closingSchema2).safeParse(event.payload);
67304
+ if (!parsed.success || !isUsageSource(event.source) || event.subject !== parsed.data.targetMissionId || !sameUsageAnchor(parsed.data.previous, prefix)) {
67305
+ throw new Error("USAGE_BOUNDARY_INVALID: source prefix or receipt changed");
67306
+ }
67307
+ if (event.kind === "usage.session.opened") {
67308
+ if (active !== void 0 || intervals.has(parsed.data.targetMissionId)) {
67309
+ throw new Error("USAGE_BOUNDARY_INVALID: overlapping or reopened interval");
67310
+ }
67311
+ active = { targetMissionId: parsed.data.targetMissionId, opening: next2 };
67312
+ intervals.set(active.targetMissionId, active);
67313
+ } else {
67314
+ const closed = closingSchema2.parse(event.payload);
67315
+ if (active === void 0 || active.targetMissionId !== closed.targetMissionId || !sameUsageAnchor(active.opening, closed.opening)) {
67316
+ throw new Error("USAGE_BOUNDARY_INVALID: closure does not match the active interval");
67317
+ }
67318
+ intervals.set(active.targetMissionId, { ...active, closing: next2 });
67319
+ active = void 0;
67320
+ }
67321
+ }
67322
+ prefix = next2;
67323
+ }
67324
+ return { prefix, intervals, ...active === void 0 ? {} : { active } };
67325
+ }
67326
+
67327
+ // src/lib/runs/usage-sessions.ts
67328
+ var requestSchema = external_exports.strictObject({
67329
+ root: external_exports.string().min(1),
67330
+ missionId: usageMissionId,
67331
+ sourceMissionId: usageMissionId,
67332
+ action: external_exports.enum(["bind", "unbind"])
67333
+ });
67334
+ async function readUsageJournal(root, missionId) {
67335
+ const path3 = await eventLogPath(root, usageMissionId.parse(missionId));
67336
+ const stream2 = replayEventLog(await requireData(root, relative(root, path3), MAX_EVENT_LOG_BYTES));
67337
+ if (stream2.continuity !== "complete" || stream2.duplicateEventIds > 0 || stream2.events.some((event) => event.missionId !== missionId || event.correlationId !== missionId)) {
67338
+ throw new Error("USAGE_SOURCE_INTEGRITY: unreadable, duplicate or mixed journal; no usage attributed");
67339
+ }
67340
+ return stream2.events;
67341
+ }
67342
+ async function reference(root, target, source2, interval, write3) {
67343
+ try {
67344
+ const eventId3 = usageEventId("reference", target, source2);
67345
+ const existing = (await readUsageJournal(root, target)).find((event) => event.eventId === eventId3);
67346
+ const persistedSource = existing !== void 0 && isUsageSource(existing.source) ? existing.source : USAGE_SOURCE;
67347
+ await write3({
67348
+ root,
67349
+ missionId: target,
67350
+ eventId: eventId3,
67351
+ draft: {
67352
+ source: persistedSource,
67353
+ kind: "usage.session.linked",
67354
+ subject: source2,
67355
+ correlationId: target,
67356
+ payload: { sourceMissionId: source2, opening: interval.opening }
67357
+ },
67358
+ validate: (events) => {
67359
+ observedMissionLifecycle(events);
67360
+ if (events.filter((event) => event.kind === "usage.session.linked").length >= MAX_USAGE_LINKS) {
67361
+ throw new Error("USAGE_LINK_LIMIT: at most 32 source journals per mission");
67362
+ }
67363
+ }
67364
+ });
67365
+ } catch (error62) {
67366
+ if (error62 instanceof Error && error62.message.startsWith("USAGE_LINK_LIMIT:")) throw error62;
67367
+ throw new Error("USAGE_REFERENCE_PENDING: source receipt is durable; retry the same command to repair the target reference");
67368
+ }
67369
+ }
67370
+ async function changeUsageSession(input2, write3 = writeSequencedEventOnce) {
67371
+ const request = requestSchema.parse(input2);
67372
+ const { root, missionId, sourceMissionId } = request;
67373
+ if (sourceMissionId === missionId) throw new Error("USAGE_SELF_LINK: source and target must differ");
67374
+ const targetEvents = await readUsageJournal(root, missionId);
67375
+ observedMissionLifecycle(targetEvents);
67376
+ const interval = await changeSourceInterval(request, targetEvents, write3);
67377
+ try {
67378
+ await reference(root, missionId, sourceMissionId, interval, write3);
67379
+ } catch (error62) {
67380
+ if (!(error62 instanceof Error) || !error62.message.startsWith("USAGE_LINK_LIMIT:")) throw error62;
67381
+ try {
67382
+ await changeSourceInterval({ ...request, action: "unbind" }, targetEvents, write3);
67383
+ } catch {
67384
+ throw new Error(`USAGE_CAPACITY_CLEANUP_PENDING: target is full; source closure is unconfirmed. Restore source access and run mission usage-unbind --id ${missionId} --source ${sourceMissionId}; the full target cannot accept this reference`);
67385
+ }
67386
+ throw new Error("USAGE_LINK_LIMIT: target is full; excess source interval is closed; no reference can be added");
67387
+ }
67388
+ return { sourceMissionId, status: interval.closing === void 0 ? "open" : "closed", interval };
67389
+ }
67390
+ async function changeSourceInterval(request, targetEvents, write3) {
67391
+ const { root, missionId, sourceMissionId, action } = request;
67392
+ for (let attempt = 0; attempt < 3; attempt += 1) {
67393
+ const scanned = scanUsageSource(await readUsageJournal(root, sourceMissionId), sourceMissionId);
67394
+ const interval = scanned.intervals.get(missionId);
67395
+ if (interval !== void 0 && (action === "bind" || interval.closing !== void 0)) {
67396
+ return interval;
67397
+ }
67398
+ if (action === "unbind" && interval === void 0) throw new Error("USAGE_NOT_BOUND: no prospective interval exists");
67399
+ if (action === "bind") {
67400
+ requireOpenMission(targetEvents);
67401
+ if (scanned.active !== void 0) throw new Error("USAGE_SOURCE_BUSY: close the active target before binding another");
67402
+ if (targetEvents.filter((event) => event.kind === "usage.session.linked").length >= MAX_USAGE_LINKS) {
67403
+ throw new Error("USAGE_LINK_LIMIT: at most 32 source journals per mission");
67404
+ }
67405
+ }
67406
+ try {
67407
+ await write3({
67408
+ root,
67409
+ missionId: sourceMissionId,
67410
+ eventId: usageEventId(action, missionId, sourceMissionId),
67411
+ draft: {
67412
+ source: USAGE_SOURCE,
67413
+ kind: action === "bind" ? "usage.session.opened" : "usage.session.closed",
67414
+ subject: missionId,
67415
+ correlationId: sourceMissionId,
67416
+ payload: {
67417
+ targetMissionId: missionId,
67418
+ previous: scanned.prefix,
67419
+ ...interval === void 0 ? {} : { opening: interval.opening }
67420
+ }
67421
+ },
67422
+ validate: (events) => {
67423
+ if (!sameUsageAnchor(scanUsageSource(events, sourceMissionId).prefix, scanned.prefix)) {
67424
+ throw new Error("USAGE_SOURCE_CHANGED: source appended during binding; retry");
67425
+ }
67426
+ }
67427
+ });
67428
+ } catch (error62) {
67429
+ if (error62 instanceof Error && (error62.message.startsWith("USAGE_SOURCE_CHANGED:") || error62.message.startsWith("HOOK_EVENT_ID_CONFLICT:"))) continue;
67430
+ throw error62;
67431
+ }
67432
+ const updated = scanUsageSource(await readUsageJournal(root, sourceMissionId), sourceMissionId).intervals.get(missionId);
67433
+ if (updated === void 0) throw new Error("USAGE_BOUNDARY_INVALID: written interval is missing");
67434
+ return updated;
67435
+ }
67436
+ throw new Error("USAGE_SOURCE_CHANGED: concurrent writes prevented a stable boundary; retry the same command");
67437
+ }
67438
+ async function readUsageSessions(root, missionId, events) {
67439
+ const references = events.filter((event) => event.missionId === missionId && event.kind === "usage.session.linked");
67440
+ const scopes = [];
67441
+ const links = [];
67442
+ const notes = [];
67443
+ if (references.length > MAX_USAGE_LINKS) return {
67444
+ scopes,
67445
+ links,
67446
+ notes: ["Linked usage unavailable: source reference limit exceeded."]
67447
+ };
67448
+ const seen = /* @__PURE__ */ new Set();
67449
+ const sourceCounts = /* @__PURE__ */ new Map();
67450
+ for (const event of references) {
67451
+ const parsed = usageReferenceSchema.safeParse(event.payload);
67452
+ if (parsed.success) sourceCounts.set(
67453
+ parsed.data.sourceMissionId,
67454
+ (sourceCounts.get(parsed.data.sourceMissionId) ?? 0) + 1
67455
+ );
67456
+ }
67457
+ for (const event of references) {
67458
+ const parsed = usageReferenceSchema.safeParse(event.payload);
67459
+ const source2 = parsed.success ? parsed.data.sourceMissionId : "unknown";
67460
+ if (seen.has(source2)) continue;
67461
+ seen.add(source2);
67462
+ try {
67463
+ if (!parsed.success || !isUsageSource(event.source) || event.subject !== source2 || event.correlationId !== missionId || source2 === missionId || sourceCounts.get(source2) !== 1) {
67464
+ throw new Error("USAGE_REFERENCE_INVALID");
67465
+ }
67466
+ const sourceEvents = await readUsageJournal(root, source2);
67467
+ const interval = scanUsageSource(sourceEvents, source2).intervals.get(missionId);
67468
+ if (interval === void 0 || !sameUsageAnchor(interval.opening, parsed.data.opening)) {
67469
+ throw new Error("USAGE_BOUNDARY_INVALID");
67470
+ }
67471
+ scopes.push({ missionId: source2, events: sourceEvents.filter((candidate) => candidate.seq > interval.opening.seq && (interval.closing === void 0 || candidate.seq < interval.closing.seq)) });
67472
+ links.push({ sourceMissionId: source2, status: interval.closing === void 0 ? "open" : "closed", interval });
67473
+ notes.push(`${source2}: ${interval.closing === void 0 ? "provisional/shared-session" : "closed shared-session interval"}; explicit attribution, not worker isolation or authentication.`);
67474
+ } catch {
67475
+ links.push({ sourceMissionId: source2, status: "unavailable" });
67476
+ notes.push(`${source2}: linked usage unavailable; no counts attributed from this source.`);
67477
+ }
67478
+ }
67479
+ return { scopes, links, notes };
67480
+ }
67481
+
67482
+ // src/lib/runs/usage-advisory.ts
67483
+ init_esm_shims();
67484
+ var advisorySchema = external_exports.strictObject({
67485
+ root: external_exports.string().min(1),
67486
+ missionId: usageMissionId,
67487
+ specialistId: external_exports.string().regex(/^core:[a-z0-9]+(?:-[a-z0-9]+)*$/),
67488
+ runtime: external_exports.enum(["claude", "codex"]),
67489
+ contextId: external_exports.string().refine(validNativeContextId)
67490
+ });
67491
+ async function recordUsageAdvisory(input2) {
67492
+ const request = advisorySchema.parse(input2);
67493
+ const specialists = await loadSpecialists(await findCoreSource());
67494
+ if (!specialists.some((specialist) => specialist.id === request.specialistId)) {
67495
+ throw new Error("USAGE_SPECIALIST_UNKNOWN: use a canonical specialist role from the catalogue");
67496
+ }
67497
+ await readUsageJournal(request.root, request.missionId);
67498
+ const recorded = await writeSequencedEventOnce({
67499
+ root: request.root,
67500
+ missionId: request.missionId,
67501
+ eventId: usageEventId("advisory", request.missionId, request.runtime, request.contextId),
67502
+ draft: {
67503
+ source: "coordinator-observed",
67504
+ kind: "usage.advisory.started",
67505
+ subject: request.specialistId,
67506
+ correlationId: request.missionId,
67507
+ payload: { runtime: request.runtime, contextId: request.contextId }
67508
+ },
67509
+ validate: requireOpenMission
67510
+ });
67511
+ return { eventId: recorded.event.eventId, provenance: "coordinator-observed" };
67512
+ }
67513
+
67514
+ // src/commands/mission-usage.ts
67515
+ var MISSION_ID10 = /^mis_[A-Za-z0-9_-]{8,100}$/;
67516
+ function parseUsageCommand(input2, helpers) {
67517
+ const { subcommand, options: options2, divider: divider2 } = input2;
67518
+ const { invalid: invalid17, valueAfter: valueAfter4, missionIdFrom: missionIdFrom2, validateOptions: validateOptions3 } = helpers;
67519
+ if (subcommand === "usage-bind" || subcommand === "usage-unbind" || subcommand === "advisory-start") {
67520
+ if (divider2 !== -1) return invalid17("usage commands do not accept a command", "remove --");
67521
+ const names = options2.filter((value) => value.startsWith("--"));
67522
+ if (new Set(names).size !== names.length) return invalid17("duplicate usage option", "provide each option once");
67523
+ const error62 = validateOptions3(options2, subcommand === "advisory-start" ? ["--id", "--specialist", "--runtime", "--context"] : ["--id", "--source"], ["--json"]);
67524
+ if (error62 !== void 0) return invalid17(error62, `${PRODUCT_COMMAND} mission --help`);
67525
+ const missionId = missionIdFrom2(options2);
67526
+ if (typeof missionId !== "string") return missionId;
67527
+ if (subcommand !== "advisory-start") {
67528
+ const sourceMissionId = valueAfter4(options2, "--source");
67529
+ if (sourceMissionId === void 0 || !MISSION_ID10.test(sourceMissionId)) return invalid17("invalid source ID", "pass --source mis_<exact-session-journal>");
67530
+ return { kind: subcommand, missionId, sourceMissionId, json: options2.includes("--json") };
67531
+ }
67532
+ const specialistId3 = valueAfter4(options2, "--specialist");
67533
+ const runtime2 = valueAfter4(options2, "--runtime");
67534
+ const contextId = valueAfter4(options2, "--context");
67535
+ if (specialistId3 === void 0 || !/^core:[a-z0-9]+(?:-[a-z0-9]+)*$/.test(specialistId3) || runtime2 !== "claude" && runtime2 !== "codex" || contextId === void 0 || contextId.trim() === "") {
67536
+ return invalid17("advisory start needs a role, runtime and actual native context", "pass --specialist core:<role> --runtime claude|codex --context <successful-native-context>");
67537
+ }
67538
+ return { kind: "advisory-start", missionId, specialistId: specialistId3, runtime: runtime2, contextId, json: options2.includes("--json") };
67539
+ }
67540
+ return void 0;
67541
+ }
67542
+ async function runUsageCommand(parsed, journal) {
67543
+ if (parsed.kind === "usage-bind" || parsed.kind === "usage-unbind") {
67544
+ const result2 = await changeUsageSession({
67545
+ root: journal,
67546
+ missionId: parsed.missionId,
67547
+ sourceMissionId: parsed.sourceMissionId,
67548
+ action: parsed.kind === "usage-bind" ? "bind" : "unbind"
67549
+ });
67550
+ return parsed.json ? `${JSON.stringify(result2)}
67551
+ ` : `${result2.sourceMissionId}: ${result2.status}
67552
+ `;
67553
+ }
67554
+ const result = await recordUsageAdvisory({
67555
+ root: journal,
67556
+ missionId: parsed.missionId,
67557
+ specialistId: parsed.specialistId,
67558
+ runtime: parsed.runtime,
67559
+ contextId: parsed.contextId
67560
+ });
67561
+ return parsed.json ? `${JSON.stringify(result)}
67562
+ ` : `${result.eventId}: coordinator-observed advisory start
67563
+ `;
67564
+ }
67565
+
67566
+ // src/lib/runs/usage-report.ts
67567
+ init_esm_shims();
67568
+
67569
+ // src/lib/runs/usage.ts
67570
+ init_esm_shims();
67571
+
67572
+ // src/lib/runs/usage-activity.ts
67573
+ init_esm_shims();
67574
+ var MAX_ACTIVITY_ROWS = 200;
67575
+ var MAX_TEXT_ROWS = 20;
67576
+ function field7(event, name) {
67577
+ const value = event.payload;
67578
+ return value && typeof value === "object" && !Array.isArray(value) ? Object.entries(value).find(([key]) => key === name)?.[1] : void 0;
67579
+ }
67580
+ function dispatchIdentity(event) {
67581
+ const stage = field7(event, "stage");
67582
+ const round = field7(event, "reviewRound");
67583
+ const version3 = field7(event, "contractVersion");
67584
+ const hash7 = field7(event, "inputHash");
67585
+ if (!["pre-implementation", "post-implementation"].includes(String(stage)) || typeof round !== "number" || !Number.isSafeInteger(round) || round < 1 || typeof version3 !== "number" || !Number.isSafeInteger(version3) || version3 < 1 || typeof hash7 !== "string" || !/^sha256:[a-f0-9]{64}$/.test(hash7)) return void 0;
67586
+ return canonicalJsonHash([
67587
+ event.missionId,
67588
+ event.source,
67589
+ event.subject,
67590
+ event.causationId ?? "",
67591
+ stage ?? "",
67592
+ round,
67593
+ version3,
67594
+ hash7,
67595
+ field7(event, "reviewSubject") ?? "",
67596
+ field7(event, "reviewScope") ?? ""
67597
+ ]);
67598
+ }
67599
+ function task(event, advisory) {
67600
+ if (advisory) return "advisory";
67601
+ const stage = field7(event, "stage");
67602
+ const round = field7(event, "reviewRound");
67603
+ return ["pre-implementation", "post-implementation"].includes(String(stage)) && typeof round === "number" && Number.isSafeInteger(round) && round > 0 ? `${stage} / round ${round}` : "specialist work (task unknown)";
67604
+ }
67605
+ function projectSpecialistActivity(input2) {
67606
+ const observations = [];
67607
+ const starts = /* @__PURE__ */ new Map();
67608
+ const invocationEvents = /* @__PURE__ */ new Map();
67609
+ const ended = new Set(input2.endedScopes ?? []);
67610
+ for (const event of input2.events) {
67611
+ if (event.kind === "mission.closed") ended.add(event.missionId);
67612
+ const advisory = event.kind === "usage.advisory.started" && event.source === "coordinator-observed";
67613
+ if (!advisory && !["specialist.started", "specialist.completed", "specialist.failed"].includes(event.kind)) continue;
67614
+ const specialist = /^core:([a-z0-9]+(?:-[a-z0-9]+)*)$/.exec(event.subject)?.[1];
67615
+ if (specialist === void 0) continue;
67616
+ const rawRuntime = advisory ? field7(event, "runtime") : /^runtime:(claude|codex)$/.exec(event.source)?.[1];
67617
+ const runtime2 = rawRuntime === "claude" || rawRuntime === "codex" ? rawRuntime : "unknown";
67618
+ if (advisory && runtime2 === "unknown") continue;
67619
+ const context2 = field7(event, "contextId");
67620
+ const nativeContextId = validNativeContextId(context2) ? context2 : "unknown";
67621
+ const dispatch2 = advisory ? void 0 : dispatchIdentity(event);
67622
+ const key = dispatch2 !== void 0 && nativeContextId !== "unknown" ? canonicalJsonHash([dispatch2, nativeContextId]) : void 0;
67623
+ const reference2 = field7(event, "reviewInvocationEventId");
67624
+ const referenced = typeof reference2 === "string" ? invocationEvents.get(`${event.missionId}:${reference2}`) : void 0;
67625
+ const previous = reference2 !== void 0 ? referenced !== void 0 && referenced.dispatch === dispatch2 && (nativeContextId === "unknown" || referenced.row.nativeContextId === nativeContextId) ? referenced : void 0 : key === void 0 ? void 0 : starts.get(key);
67626
+ const terminal = event.kind === "specialist.completed" ? "completed" : event.kind === "specialist.failed" ? "failed" : void 0;
67627
+ if (terminal !== void 0 && previous?.started && dispatch2 !== void 0 && runtime2 !== "unknown") {
67628
+ previous.row = {
67629
+ ...previous.row,
67630
+ observedState: terminal,
67631
+ outcome: terminal,
67632
+ lastEventId: event.eventId,
67633
+ lastObservedAt: event.ts
67634
+ };
67635
+ continue;
67636
+ }
67637
+ const started = !advisory && event.kind === "specialist.started";
67638
+ const reason2 = advisory ? "start observed; no advisory completion telemetry" : terminal !== void 0 ? "terminal without matching start" : dispatch2 === void 0 || runtime2 === "unknown" ? "dispatch metadata unavailable" : void 0;
67639
+ const observation3 = { started, ...dispatch2 === void 0 ? {} : { dispatch: dispatch2 }, row: {
67640
+ kind: advisory ? "advisory" : "specialist",
67641
+ specialist,
67642
+ sourceMissionId: event.missionId,
67643
+ attribution: event.missionId === input2.missionId ? "mission" : "shared-session",
67644
+ runtime: runtime2,
67645
+ nativeContextId,
67646
+ task: task(event, advisory),
67647
+ observedState: reason2 === void 0 ? "running" : "unknown",
67648
+ provenance: advisory ? "coordinator-observed" : "runtime-receipt",
67649
+ lastEventId: event.eventId,
67650
+ lastObservedAt: event.ts,
67651
+ ...terminal === void 0 ? {} : { outcome: terminal },
67652
+ ...reason2 === void 0 ? {} : { reason: reason2 }
67653
+ } };
67654
+ observations.push(observation3);
67655
+ if (started) {
67656
+ invocationEvents.set(`${event.missionId}:${event.eventId}`, observation3);
67657
+ if (key !== void 0) starts.set(key, observation3);
67658
+ }
67659
+ }
67660
+ const activity = observations.slice(0, MAX_ACTIVITY_ROWS).map(({ row: row2 }) => {
67661
+ if (row2.observedState !== "running") return row2;
67662
+ const reason2 = input2.incomplete ? "journal incomplete" : ended.has(input2.missionId) || ended.has(row2.sourceMissionId) ? "observation ended without a terminal receipt" : void 0;
67663
+ return reason2 === void 0 ? row2 : { ...row2, observedState: "unknown", reason: reason2 };
67664
+ });
67665
+ return { activity, activityOmitted: Math.max(0, observations.length - activity.length) };
67666
+ }
67667
+ var cell = (value) => value.replace(/[\\|[\]`<>]/g, "\\$&");
67668
+ function renderSpecialistActivity(report) {
67669
+ if (report.activity.length === 0) return ["Specialist activity unknown: no linked execution observations."];
67670
+ const visible = report.activity.slice(0, MAX_TEXT_ROWS);
67671
+ const omitted = report.activityOmitted + report.activity.length - visible.length;
67672
+ return [
67673
+ "Specialist activity (last recorded observation, not live presence)",
67674
+ "| Kind / provenance | Specialist | Task | Observed state | Native identity | Source scope |",
67675
+ "| --- | --- | --- | --- | --- | --- |",
67676
+ ...visible.map((row2) => `| ${row2.kind} / ${row2.provenance} | ${row2.specialist} | ${cell(row2.task)} | ${row2.observedState}${row2.reason === void 0 ? "" : ` (${row2.reason})`} | ${row2.runtime}:${cell(row2.nativeContextId)} | ${row2.attribution}:${cell(row2.sourceMissionId)} |`),
67677
+ ...omitted > 0 ? [`${omitted} activity observation(s) omitted; JSON includes up to ${MAX_ACTIVITY_ROWS} rows.`] : []
67678
+ ];
67679
+ }
67680
+
67681
+ // src/lib/runs/usage.ts
67682
+ function field8(payload, key) {
67683
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) return void 0;
67684
+ const value = Object.entries(payload).find(([name]) => name === key)?.[1];
67685
+ return typeof value === "string" ? value : void 0;
67686
+ }
67687
+ function observation2(event) {
67688
+ if (event.subject.startsWith("skill:") && event.source === "runtime:claude") {
67689
+ if (event.kind === "runtime.tool.started" && field8(event.payload, "category") === "skill") {
67690
+ return { type: "skill", hit: true };
67691
+ }
67692
+ if (event.kind === "runtime.tool.completed") {
67693
+ return { type: "skill", hit: false, outcome: field8(event.payload, "status") ?? "unknown" };
67694
+ }
67695
+ }
67696
+ if (event.subject.startsWith("hook:") && event.kind === "hook.completed") {
67697
+ return { type: "hook", hit: true, outcome: field8(event.payload, "status") ?? "unknown" };
67698
+ }
67699
+ if (event.kind === "usage.advisory.started" && event.source === "coordinator-observed" && event.subject.startsWith("core:") && ["claude", "codex"].includes(field8(event.payload, "runtime") ?? "")) {
67700
+ return { type: "advisory", hit: true };
67701
+ }
67702
+ if (event.subject.startsWith("core:") && event.kind === "specialist.started") {
67703
+ return { type: "specialist", hit: true };
67704
+ }
67705
+ if (event.subject.startsWith("core:") && ["specialist.completed", "specialist.failed"].includes(event.kind)) {
67706
+ return { type: "specialist", hit: false, outcome: event.kind.slice("specialist.".length) };
67707
+ }
67708
+ return void 0;
67709
+ }
67710
+ function projectMissionUsage(input2) {
67711
+ const rows = /* @__PURE__ */ new Map();
67712
+ for (const entry of input2.catalog) {
67713
+ if (entry.type !== "skill" && entry.type !== "hook" && entry.type !== "specialist") continue;
67714
+ rows.set(`${entry.type}:${entry.name}`, {
67715
+ type: entry.type,
67716
+ name: entry.name,
67717
+ catalogued: true,
67718
+ observedHits: 0,
67719
+ outcomes: {},
67720
+ runtimeHits: {}
67721
+ });
67722
+ }
67723
+ const channels = /* @__PURE__ */ new Set();
67724
+ const seen = /* @__PURE__ */ new Set();
67725
+ const runtimeChannels = /* @__PURE__ */ new Set();
67726
+ const scopes = [{ missionId: input2.missionId, events: input2.events }, ...input2.linkedScopes ?? []];
67727
+ const events = scopes.flatMap((scope) => scope.events.filter((item) => item.missionId === scope.missionId)).filter((event) => {
67728
+ const identity2 = `${event.missionId}:${event.eventId}`;
67729
+ if (seen.has(identity2)) return false;
67730
+ seen.add(identity2);
67731
+ return true;
67732
+ });
67733
+ for (const event of events) {
67734
+ const observed2 = observation2(event);
67735
+ if (observed2 === void 0) continue;
67736
+ const rawName = event.subject.slice(event.subject.indexOf(":") + 1);
67737
+ const name = observed2.type === "skill" ? activationName("skill", rawName.startsWith("core/") ? rawName.slice(5) : rawName) : input2.hookSubjects[event.subject] ?? rawName;
67738
+ if (!/^[a-zA-Z0-9]+(?:[-:/][a-zA-Z0-9]+)*$/.test(name)) continue;
67739
+ const runtime2 = observed2.type === "advisory" ? field8(event.payload, "runtime") ?? "unknown" : /^runtime:(claude|codex|unknown)$/.test(event.source) ? event.source.slice("runtime:".length) : "unattributed";
67740
+ runtimeChannels.add(`${observed2.type}:${runtime2}`);
67741
+ channels.add(observed2.type);
67742
+ const key = `${observed2.type}:${name}`;
67743
+ const row2 = rows.get(key) ?? {
67744
+ type: observed2.type,
67745
+ name,
67746
+ catalogued: observed2.type === "advisory" && input2.catalog.some((entry) => entry.type === "specialist" && entry.name === name),
67747
+ observedHits: 0,
67748
+ outcomes: {},
67749
+ runtimeHits: {}
67750
+ };
67751
+ if (observed2.hit) {
67752
+ row2.observedHits += 1;
67753
+ row2.runtimeHits[runtime2] = (row2.runtimeHits[runtime2] ?? 0) + 1;
67754
+ }
67755
+ if (observed2.outcome !== void 0) {
67756
+ const outcome = ["ok", "error", "skipped", "degraded", "blocked", "completed", "failed"].includes(observed2.outcome) ? observed2.outcome : "unknown";
67757
+ row2.outcomes[outcome] = (row2.outcomes[outcome] ?? 0) + 1;
67758
+ }
67759
+ rows.set(key, row2);
67760
+ }
67761
+ return {
67762
+ missionId: input2.missionId,
67763
+ ...projectSpecialistActivity({
67764
+ missionId: input2.missionId,
67765
+ events,
67766
+ ...input2.endedScopes === void 0 ? {} : { endedScopes: input2.endedScopes },
67767
+ ...input2.incomplete === void 0 ? {} : { incomplete: input2.incomplete }
67768
+ }),
67769
+ rows: [...rows.values()].map((row2) => ({
67770
+ ...row2,
67771
+ observedHits: channels.has(row2.type) ? row2.observedHits : "unknown",
67772
+ runtimeHits: Object.fromEntries([.../* @__PURE__ */ new Set(["claude", "codex", ...Object.keys(row2.runtimeHits)])].map((runtime2) => [runtime2, runtimeChannels.has(`${row2.type}:${runtime2}`) ? row2.runtimeHits[runtime2] ?? 0 : "unknown"]))
67773
+ })).sort((a, b2) => `${a.type}:${a.name}`.localeCompare(`${b2.type}:${b2.name}`, "en")),
67774
+ notes: [
67775
+ ...!channels.has("hook") && !channels.has("skill") ? ["hook/skill telemetry not linked to this mission."] : [],
67776
+ ...["skill", "hook", "specialist", "advisory"].filter((kind2) => !channels.has(kind2)).map((kind2) => `${kind2}: unknown; no linked execution telemetry.`),
67777
+ "Hits are observed lower bounds. Zero means no recorded hit, not proof of non-use; gaps remain possible.",
67778
+ "Codex SKILL.md reads are loads, not observable native skill invocations; no skill hits are inferred from them.",
67779
+ ...channels.has("advisory") ? ["Advisory starts are coordinator-observed declarations, separate from formal specialist dispatch; no completion or verdict claimed."] : [],
67780
+ "Counts do not prove applicability, instruction compliance, TDD or code quality. Missing telemetry is not a delivery gate."
67781
+ ]
67782
+ };
67783
+ }
67784
+ function renderMissionUsage(report) {
67785
+ const observed2 = report.rows.filter((row2) => typeof row2.observedHits === "number" && row2.observedHits > 0 || Object.keys(row2.outcomes).length > 0);
67786
+ return [
67787
+ ...renderSpecialistActivity(report),
67788
+ "",
67789
+ "Usage recap (explicit mission linkage only)",
67790
+ ...report.notes.map((note) => `- ${note}`),
67791
+ ...["skill", "hook", "specialist", "advisory"].map((kind2) => {
67792
+ const rows = report.rows.filter((row2) => row2.type === kind2);
67793
+ return `${kind2}: ${rows.filter((row2) => row2.observedHits === 0).length} zero observed, ${rows.filter((row2) => row2.observedHits === "unknown").length} unknown catalogue entries.`;
67794
+ }),
67795
+ ...observed2.length === 0 ? ["No linked execution observations. Full inventory: void-machine cheatsheet --format markdown."] : [
67796
+ "| Kind | Name | Observed hits | Outcomes | Telemetry |",
67797
+ "| --- | --- | --- | --- | --- |",
67798
+ ...observed2.map((row2) => `| ${row2.type} | ${row2.name} | ${row2.observedHits} | ${Object.entries(row2.outcomes).map(([status3, count]) => `${status3}=${count}`).join(", ") || "-"} | ${Object.entries(row2.runtimeHits).map(([runtime2, hits]) => `${runtime2}=${hits}`).join(", ")}${row2.catalogued ? "" : "; outside current catalogue"} |`)
67799
+ ]
67800
+ ].join("\n");
67801
+ }
67802
+
67803
+ // src/lib/runs/usage-report.ts
67804
+ async function loadMissionUsage(root, missionId, stream2) {
67805
+ const core = await findCoreSource();
67806
+ const catalog = await loadCatalog(core);
67807
+ const hookSubjects = {};
67808
+ for (const entry of catalog.filter((item) => item.type === "hook")) {
67809
+ const command2 = hookRunnerCommand(await requireData(core, `hooks/${entry.name}.sh`, 64 * 1024));
67810
+ if (command2 !== void 0) hookSubjects[`hook:${command2.split(" ").at(-1)}`] = entry.name;
67811
+ }
67812
+ const linked = await readUsageSessions(root, missionId, stream2.events);
67813
+ const incomplete = stream2.continuity !== "complete" || stream2.events.some((event) => event.missionId !== missionId);
67814
+ const report = projectMissionUsage({
67815
+ missionId,
67816
+ events: stream2.events,
67817
+ catalog,
67818
+ hookSubjects,
67819
+ linkedScopes: linked.scopes,
67820
+ incomplete,
67821
+ endedScopes: linked.links.filter((link3) => link3.status !== "open").map((link3) => link3.sourceMissionId)
67822
+ });
67823
+ const notes = [...linked.notes, ...report.notes];
67824
+ if (incomplete) {
67825
+ notes.unshift("Journal incomplete or mixed: counts cover readable linked events only, never complete usage.");
67826
+ }
67827
+ try {
67828
+ const stored = await loadMissionControllerPlan(root, missionId);
67829
+ const bound = stream2.events.some((event) => event.missionId === missionId && event.kind === "mission.started" && event.payload && typeof event.payload === "object" && !Array.isArray(event.payload) && Object.entries(event.payload).some(([key, value]) => key === "routingHash" && value === stored.routingHash));
67830
+ notes.unshift(bound ? `Ticket binding: ${JSON.stringify(stored.ticket.path)} (${stored.ticket.contentHash}).` : "Ticket binding unverified; scope is this mission journal, not a proven ticket.");
67831
+ } catch {
67832
+ notes.unshift("Ticket binding unavailable; scope is this mission/session journal, not a proven ticket.");
67833
+ }
67834
+ return { ...report, notes, links: linked.links };
67835
+ }
67836
+
67165
67837
  // src/lib/runs/inspect-current.ts
67166
67838
  init_esm_shims();
67167
- async function inspectCurrentMission(roots, missionId, secrets) {
67839
+ async function inspectCurrentMission(roots, missionId, secrets, options2 = {}) {
67168
67840
  for (let attempt = 0; attempt < 2; attempt += 1) {
67169
67841
  const before = await computeProjectState2(roots.workRoot);
67170
67842
  const inspected = await inspectMission(
67171
67843
  roots.installRoot,
67172
67844
  missionId,
67173
67845
  { dependencies: { "git:working-tree": before.diffHash } },
67174
- { secrets }
67846
+ { secrets, ...options2 }
67175
67847
  );
67176
67848
  const after = await computeProjectState2(roots.workRoot);
67177
67849
  if (before.diffHash === after.diffHash) {
@@ -67185,9 +67857,9 @@ async function inspectCurrentMission(roots, missionId, secrets) {
67185
67857
 
67186
67858
  // src/lib/runs/mission-recovery.ts
67187
67859
  init_esm_shims();
67188
- async function recordStoppedMissionRecovery(root, missionId, request, observation2) {
67860
+ async function recordStoppedMissionRecovery(root, missionId, request, observation3) {
67189
67861
  const inspected = await inspectMission(root, missionId, { dependencies: {} });
67190
- const decision = planStoppedMissionRecovery({ stream: inspected.stream, request, observation: observation2 });
67862
+ const decision = planStoppedMissionRecovery({ stream: inspected.stream, request, observation: observation3 });
67191
67863
  if (decision.kind === "refused") {
67192
67864
  throw new Error(`MISSION_RECOVERY_REFUSED: ${decision.code}: ${decision.reasons.join("; ")}`);
67193
67865
  }
@@ -67259,7 +67931,7 @@ function parseMissionRecoveryRequest(value) {
67259
67931
  };
67260
67932
  if (disposition["kind"] === "controller-defect") {
67261
67933
  const defect = disposition["defect"];
67262
- if (!exact2(disposition, ["kind", "defect"]) || defect !== "partial-fanout-round" && defect !== "stale-input-dispatch" && defect !== "opaque-native-context") invalid11();
67934
+ if (!exact2(disposition, ["kind", "defect"]) || defect !== "partial-fanout-round" && defect !== "stale-input-dispatch" && defect !== "opaque-native-context" && defect !== "targeted-review-context") invalid11();
67263
67935
  return { ...base, disposition: { kind: "controller-defect", defect } };
67264
67936
  }
67265
67937
  if (disposition["kind"] === "evidence-disposition") {
@@ -67383,15 +68055,15 @@ async function observeSpecialistMigrationAssets(coreRoot, installRoot, runtime2)
67383
68055
  nativeContractVersion: target.version
67384
68056
  };
67385
68057
  }
67386
- async function recordSpecialistContractMigration(root, missionId, request, observation2) {
68058
+ async function recordSpecialistContractMigration(root, missionId, request, observation3) {
67387
68059
  const [inspected, stored] = await Promise.all([
67388
68060
  inspectMission(root, missionId, { dependencies: {} }),
67389
68061
  loadMissionControllerPlan(root, missionId)
67390
68062
  ]);
67391
- if (canonicalJsonHash(stored.plan) !== canonicalJsonHash(observation2.plan)) {
68063
+ if (canonicalJsonHash(stored.plan) !== canonicalJsonHash(observation3.plan)) {
67392
68064
  invalid12("migration observation does not match the immutable controller plan");
67393
68065
  }
67394
- const decision = planSpecialistContractMigration({ stream: inspected.stream, request, observation: observation2 });
68066
+ const decision = planSpecialistContractMigration({ stream: inspected.stream, request, observation: observation3 });
67395
68067
  if (decision.kind === "refused") {
67396
68068
  const code2 = decision.code === "stale-migration" && canonicalJsonHash(inspected.stream.events) !== request.expectedJournalHash ? "stale-journal" : decision.code;
67397
68069
  throw new Error(`SPECIALIST_CONTRACT_MIGRATION_REFUSED: ${code2}: ${decision.reasons.join("; ")}`);
@@ -67451,7 +68123,7 @@ init_esm_shims();
67451
68123
  function record25(value) {
67452
68124
  return typeof value === "object" && value !== null && !Array.isArray(value);
67453
68125
  }
67454
- function field7(value, key) {
68126
+ function field9(value, key) {
67455
68127
  return record25(value) ? value[key] : void 0;
67456
68128
  }
67457
68129
  function invalid13(detail) {
@@ -67459,12 +68131,12 @@ function invalid13(detail) {
67459
68131
  }
67460
68132
  function identity(events) {
67461
68133
  const start = events.find((event) => event.kind === "mission.started");
67462
- const runtime2 = start ? field7(start.payload, "runtime") : void 0;
67463
- if (!start || field7(start.payload, "runtimeAttested") !== true || runtime2 !== "codex" && runtime2 !== "claude") invalid13("native mission runtime is not attested");
68134
+ const runtime2 = start ? field9(start.payload, "runtime") : void 0;
68135
+ if (!start || field9(start.payload, "runtimeAttested") !== true || runtime2 !== "codex" && runtime2 !== "claude") invalid13("native mission runtime is not attested");
67464
68136
  return runtime2 === "codex" ? "runtime:codex" : "runtime:claude";
67465
68137
  }
67466
68138
  function freshContext(events, contextId) {
67467
- if (!validNativeContextId(contextId) || events.some((event) => field7(event.payload, "contextId") === contextId || field7(event.payload, "nativeContextId") === contextId)) invalid13("provide a fresh native author context");
68139
+ if (!validNativeContextId(contextId) || events.some((event) => field9(event.payload, "contextId") === contextId || field9(event.payload, "nativeContextId") === contextId)) invalid13("provide a fresh native author context");
67468
68140
  }
67469
68141
  function eventId2(value) {
67470
68142
  return `evt_${createHash("sha256").update(canonicalJsonHash(value)).digest("hex")}`;
@@ -67484,9 +68156,9 @@ async function requestSpecialistEvidence(roots, missionId, input2) {
67484
68156
  requireOpenMission(events);
67485
68157
  const source2 = identity(events);
67486
68158
  const original = events.find((event) => event.eventId === input2.completionEventId);
67487
- const completion = original ? parseSpecialistCompletionValue(field7(original.payload, "completion")) : void 0;
68159
+ const completion = original ? parseSpecialistCompletionValue(field9(original.payload, "completion")) : void 0;
67488
68160
  if (!original || original.kind !== "specialist.completed" || !completion || original.source !== source2 || original.subject !== completion.specialistId || completion.evidenceRequests.length === 0) invalid13("original author completion with evidence requests is required");
67489
- const requestId = eventId2({ missionId, ...input2, completionHash: canonicalJsonHash(field7(original.payload, "completion")) });
68161
+ const requestId = eventId2({ missionId, ...input2, completionHash: canonicalJsonHash(field9(original.payload, "completion")) });
67490
68162
  const existing = events.find((event) => event.eventId === requestId);
67491
68163
  if (existing) return existing;
67492
68164
  freshContext(events, input2.contextId);
@@ -67502,7 +68174,7 @@ async function requestSpecialistEvidence(roots, missionId, input2) {
67502
68174
  correlationId: missionId,
67503
68175
  payload: {
67504
68176
  completionEventId: original.eventId,
67505
- completionHash: canonicalJsonHash(field7(original.payload, "completion")),
68177
+ completionHash: canonicalJsonHash(field9(original.payload, "completion")),
67506
68178
  specialistId: completion.specialistId,
67507
68179
  nativeContextId: input2.contextId,
67508
68180
  requestId,
@@ -67524,7 +68196,7 @@ async function requestSpecialistEvidence(roots, missionId, input2) {
67524
68196
  }
67525
68197
  function exactRequest(events, input2) {
67526
68198
  const request = events.find((event) => event.eventId === input2.requestEventId);
67527
- if (!request || request.source !== "void-harness:mission.dispatch" || !["specialist.evidence-classification-requested", "specialist.evidence-discharge-requested"].includes(request.kind) || field7(request.payload, "nativeContextId") !== input2.contextId || !record25(request.payload)) {
68199
+ if (!request || request.source !== "void-harness:mission.dispatch" || !["specialist.evidence-classification-requested", "specialist.evidence-discharge-requested"].includes(request.kind) || field9(request.payload, "nativeContextId") !== input2.contextId || !record25(request.payload)) {
67528
68200
  invalid13("response must match its controller request and native context");
67529
68201
  }
67530
68202
  return request;
@@ -67532,7 +68204,7 @@ function exactRequest(events, input2) {
67532
68204
  async function validateCompletion(events, candidate, roots, expectedSource) {
67533
68205
  const proofs = events.flatMap((event) => {
67534
68206
  if (event.kind !== "evidence.recorded") return [];
67535
- const parsed = parseEvidence(field7(event.payload, "evidence"));
68207
+ const parsed = parseEvidence(field9(event.payload, "evidence"));
67536
68208
  return parsed.ok ? [{ eventId: event.eventId, evidence: parsed.value }] : [];
67537
68209
  });
67538
68210
  const discharge2 = candidate.kind === "specialist.evidence-discharged";
@@ -67546,7 +68218,7 @@ async function validateCompletion(events, candidate, roots, expectedSource) {
67546
68218
  });
67547
68219
  if (state.issues.length > 0) invalid13(state.issues.map((value) => value.detail).join("; "));
67548
68220
  if (discharge2) {
67549
- const items = field7(candidate.payload, "items");
68221
+ const items = field9(candidate.payload, "items");
67550
68222
  if (!Array.isArray(items) || items.some((item) => !record25(item) || !state.obligations.some((value) => value.obligationId === item["obligationId"] && value.discharged))) {
67551
68223
  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`);
67552
68224
  }
@@ -67590,7 +68262,7 @@ async function recordSpecialistEvidence(roots, missionId, status3, input2) {
67590
68262
  requireResponseAdmission(current, status3, input2);
67591
68263
  exactRequest(current, input2);
67592
68264
  if (status3 === "completed") {
67593
- 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);
68265
+ const started = current.find((event) => event.kind === "specialist.evidence-started" && event.source === source2 && event.subject === request.subject && event.causationId === request.eventId && field9(event.payload, "nativeContextId") === input2.contextId);
67594
68266
  if (!started) invalid13("author response needs its observed native started receipt");
67595
68267
  await validateCompletion(current, {
67596
68268
  schemaVersion: 1,
@@ -67662,7 +68334,7 @@ function parseSpecialistEvidenceResponse(status3, value) {
67662
68334
 
67663
68335
  // src/lib/runs/specialist-lifecycle.ts
67664
68336
  init_esm_shims();
67665
- var MISSION_ID10 = /^mis_[A-Za-z0-9_-]{8,100}$/;
68337
+ var MISSION_ID11 = /^mis_[A-Za-z0-9_-]{8,100}$/;
67666
68338
  var SPECIALIST_ID4 = /^core:[a-z0-9]+(?:-[a-z0-9]+)*$/;
67667
68339
  var AGENT_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
67668
68340
  var HASH7 = /^sha256:[a-f0-9]{64}$/;
@@ -67698,7 +68370,7 @@ function parseEnvelope2(value) {
67698
68370
  ...ENVELOPE_KEYS,
67699
68371
  ...value["reviewSubject"] === void 0 ? [] : ["reviewSubject"],
67700
68372
  ...value["reviewScope"] === void 0 ? [] : ["reviewScope"]
67701
- ]) || value["reviewSubject"] !== void 0 && !isReviewSubject(value["reviewSubject"]) || value["reviewScope"] !== void 0 && !isReviewScope(value["reviewScope"]) || value.schemaVersion !== 1 || typeof value.missionId !== "string" || !MISSION_ID10.test(value.missionId) || value.runtime !== "claude" && value.runtime !== "codex" || !isSpecialistId(value.specialistId) || typeof value.agentName !== "string" || !AGENT_NAME.test(value.agentName) || value.agentName !== value.specialistId.slice("core:".length) || !Number.isSafeInteger(value.contractVersion) || Number(value.contractVersion) < 1 || Number(value.contractVersion) > 1e4 || value.stage !== "pre-implementation" && value.stage !== "post-implementation" || !Number.isSafeInteger(value.reviewRound) || Number(value.reviewRound) < 1 || Number(value.reviewRound) > 8 || typeof value.inputHash !== "string" || !HASH7.test(value.inputHash)) {
68373
+ ]) || value["reviewSubject"] !== void 0 && !isReviewSubject(value["reviewSubject"]) || value["reviewScope"] !== void 0 && !isReviewScope(value["reviewScope"]) || value.schemaVersion !== 1 || typeof value.missionId !== "string" || !MISSION_ID11.test(value.missionId) || value.runtime !== "claude" && value.runtime !== "codex" || !isSpecialistId(value.specialistId) || typeof value.agentName !== "string" || !AGENT_NAME.test(value.agentName) || value.agentName !== value.specialistId.slice("core:".length) || !Number.isSafeInteger(value.contractVersion) || Number(value.contractVersion) < 1 || Number(value.contractVersion) > 1e4 || value.stage !== "pre-implementation" && value.stage !== "post-implementation" || !Number.isSafeInteger(value.reviewRound) || Number(value.reviewRound) < 1 || Number(value.reviewRound) > 8 || typeof value.inputHash !== "string" || !HASH7.test(value.inputHash)) {
67702
68374
  invalid14("dispatch envelope is malformed");
67703
68375
  }
67704
68376
  const contextPack = parseContextPackValue(value.contextPack, {
@@ -67844,7 +68516,7 @@ async function recordSpecialistLifecycle(root, missionId, input2, artifactRoot =
67844
68516
  if (lifecycle.status === "closed") invalid14("mission is closed");
67845
68517
  await rejectSupersededSpecialistContract(root, missionId, events, input2.envelope, input2.contextId);
67846
68518
  const recovery = events.filter((event) => event.kind === "mission.recovered").at(-1);
67847
- const requested = events.filter((event) => event.kind === "specialist.requested" && (recovery === void 0 || event.seq > recovery.seq) && sameDispatch(event, input2.envelope) && field8(event.payload, "runtime") === input2.envelope.runtime).at(-1);
68519
+ const requested = events.filter((event) => event.kind === "specialist.requested" && (recovery === void 0 || event.seq > recovery.seq) && sameDispatch(event, input2.envelope) && field10(event.payload, "runtime") === input2.envelope.runtime).at(-1);
67848
68520
  if (requested === void 0) invalid14("no matching specialist.requested event exists");
67849
68521
  const invocationId = await checkedReviewArtifact(artifactRoot, input2, events, requested);
67850
68522
  if (invocationId !== void 0 && input2.status === "completed") {
@@ -67868,17 +68540,17 @@ async function recordSpecialistLifecycle(root, missionId, input2, artifactRoot =
67868
68540
  if (input2.status === "started") {
67869
68541
  const existing = starts.at(-1);
67870
68542
  if (existing !== void 0) {
67871
- if (field8(existing.payload, "contextId") === input2.contextId && field8(existing.payload, "reviewerId") === input2.reviewerId) return;
67872
- const failed2 = input2.envelope.reviewSubject !== void 0 && dispatchEvents.some((event) => event.kind === "specialist.failed" && event.seq > existing.seq && sameDispatch(event, input2.envelope) && field8(event.payload, "contextId") === field8(existing.payload, "contextId"));
68543
+ if (field10(existing.payload, "contextId") === input2.contextId && field10(existing.payload, "reviewerId") === input2.reviewerId) return;
68544
+ const failed2 = input2.envelope.reviewSubject !== void 0 && dispatchEvents.some((event) => event.kind === "specialist.failed" && event.seq > existing.seq && sameDispatch(event, input2.envelope) && field10(event.payload, "contextId") === field10(existing.payload, "contextId"));
67873
68545
  if (!failed2) invalid14("dispatch already started with another contextId");
67874
68546
  }
67875
- if (recovery !== void 0 && input2.contextId !== void 0 && events.some((event) => event.kind === "specialist.started" && field8(event.payload, "contextId") === input2.contextId)) {
68547
+ if (recovery !== void 0 && input2.contextId !== void 0 && events.some((event) => event.kind === "specialist.started" && field10(event.payload, "contextId") === input2.contextId) && !canContinueNativeReview(events, requested, input2.contextId)) {
67876
68548
  invalid14("contextId was already used by a previous dispatch");
67877
68549
  }
67878
68550
  } else {
67879
- const started = starts.find((event) => input2.contextId === void 0 ? event.eventId === invocationId : field8(event.payload, "contextId") === input2.contextId);
68551
+ const started = starts.find((event) => input2.contextId === void 0 ? event.eventId === invocationId : field10(event.payload, "contextId") === input2.contextId);
67880
68552
  if (started === void 0) invalid14("no matching independent invocation specialist.started event exists");
67881
- const terminal = dispatchEvents.find((event) => sameDispatch(event, input2.envelope) && (event.kind === "specialist.completed" || event.kind === "specialist.failed" && (input2.envelope.reviewSubject === void 0 || field8(event.payload, "contextId") === input2.contextId)));
68553
+ const terminal = dispatchEvents.find((event) => sameDispatch(event, input2.envelope) && (event.kind === "specialist.completed" || event.kind === "specialist.failed" && (input2.envelope.reviewSubject === void 0 || field10(event.payload, "contextId") === input2.contextId)));
67882
68554
  if (terminal !== void 0) {
67883
68555
  if (sameDraft2(terminal, draft)) return;
67884
68556
  if (input2.envelope.reviewSubject === void 0 || terminal.kind === "specialist.completed" || input2.status !== "completed") invalid14("dispatch already has a different terminal event");
@@ -67904,7 +68576,7 @@ async function recordSpecialistLifecycle(root, missionId, input2, artifactRoot =
67904
68576
  if (observedMissionLifecycle(current).episodeId !== lifecycle.episodeId) {
67905
68577
  invalid14("mission episode changed before recording lifecycle");
67906
68578
  }
67907
- if (recovery !== void 0 && input2.status === "started" && input2.contextId !== void 0 && current.some((event) => event.kind === "specialist.started" && field8(event.payload, "contextId") === input2.contextId && event.eventId !== eventId3)) {
68579
+ if (recovery !== void 0 && input2.status === "started" && input2.contextId !== void 0 && current.some((event) => event.kind === "specialist.started" && field10(event.payload, "contextId") === input2.contextId && event.eventId !== eventId3) && !canContinueNativeReview(current, requested, input2.contextId)) {
67908
68580
  invalid14("contextId was already used by a previous dispatch");
67909
68581
  }
67910
68582
  }
@@ -67918,7 +68590,7 @@ async function checkedReviewArtifact(root, input2, events, requested) {
67918
68590
  const review = input2.completion.review;
67919
68591
  const provenance4 = review.provenance;
67920
68592
  if (provenance4.kind !== "review-artifact") return void 0;
67921
- const invocation = events.find((event) => event.kind === "specialist.started" && event.source === `runtime:${input2.envelope.runtime}` && event.seq > requested.seq && sameDispatch(event, input2.envelope) && (field8(event.payload, "reviewerId") === review.reviewerId || input2.contextId !== void 0 && field8(event.payload, "contextId") === input2.contextId));
68593
+ const invocation = events.find((event) => event.kind === "specialist.started" && event.source === `runtime:${input2.envelope.runtime}` && event.seq > requested.seq && sameDispatch(event, input2.envelope) && (field10(event.payload, "reviewerId") === review.reviewerId || input2.contextId !== void 0 && field10(event.payload, "contextId") === input2.contextId));
67922
68594
  if (invocation === void 0) invalid14("review artifact has no matching independent invocation");
67923
68595
  const loaded = await readBoundedProjectFile({
67924
68596
  root,
@@ -67953,15 +68625,15 @@ async function rejectSupersededSpecialistContract(root, missionId, events, envel
67953
68625
  if (envelope.contractVersion !== migration.receipt.toVersion || envelope.stage !== "post-implementation" || envelope.reviewRound !== migration.receipt.reviewRound || envelope.inputHash !== migration.receipt.targetInputHash) {
67954
68626
  invalid14("dispatch is superseded by the authenticated specialist contract migration");
67955
68627
  }
67956
- if (contextId !== void 0 && events.some((event) => event.seq < migration.seq && field8(event.payload, "contextId") === contextId)) {
68628
+ if (contextId !== void 0 && events.some((event) => event.seq < migration.seq && field10(event.payload, "contextId") === contextId)) {
67957
68629
  invalid14("migrated specialist requires a fresh native context");
67958
68630
  }
67959
68631
  }
67960
- function field8(value, key) {
68632
+ function field10(value, key) {
67961
68633
  return isRecord11(value) ? value[key] : void 0;
67962
68634
  }
67963
68635
  function sameDispatch(event, envelope) {
67964
- return event.missionId === envelope.missionId && event.subject === envelope.specialistId && field8(event.payload, "stage") === envelope.stage && field8(event.payload, "reviewRound") === envelope.reviewRound && field8(event.payload, "inputHash") === envelope.inputHash && field8(event.payload, "contractVersion") === envelope.contractVersion && (envelope.reviewSubject === void 0 || field8(event.payload, "reviewSubject") !== void 0 && canonicalJsonHash(field8(event.payload, "reviewSubject")) === canonicalJsonHash(envelope.reviewSubject)) && (envelope.reviewScope === void 0 || field8(event.payload, "reviewScope") !== void 0 && canonicalJsonHash(field8(event.payload, "reviewScope")) === canonicalJsonHash(envelope.reviewScope));
68636
+ return event.missionId === envelope.missionId && event.subject === envelope.specialistId && field10(event.payload, "stage") === envelope.stage && field10(event.payload, "reviewRound") === envelope.reviewRound && field10(event.payload, "inputHash") === envelope.inputHash && field10(event.payload, "contractVersion") === envelope.contractVersion && (envelope.reviewSubject === void 0 || field10(event.payload, "reviewSubject") !== void 0 && canonicalJsonHash(field10(event.payload, "reviewSubject")) === canonicalJsonHash(envelope.reviewSubject)) && (envelope.reviewScope === void 0 || field10(event.payload, "reviewScope") !== void 0 && canonicalJsonHash(field10(event.payload, "reviewScope")) === canonicalJsonHash(envelope.reviewScope));
67965
68637
  }
67966
68638
  function sameDraft2(event, draft) {
67967
68639
  return event.source === draft.source && event.kind === draft.kind && event.subject === draft.subject && event.correlationId === draft.correlationId && event.causationId === draft.causationId && JSON.stringify(event.payload) === JSON.stringify(draft.payload);
@@ -68062,7 +68734,7 @@ async function recordSpecialistRequests(root, missionId, envelopes, planHash) {
68062
68734
  init_esm_shims();
68063
68735
 
68064
68736
  // package.json
68065
- var version2 = "5.0.7";
68737
+ var version2 = "6.0.0";
68066
68738
 
68067
68739
  // src/lib/runs/verify.ts
68068
68740
  var MAX_CAPTURE_BYTES = 64 * 1024;
@@ -68189,7 +68861,7 @@ async function verifyMissionCommand(options2) {
68189
68861
  }
68190
68862
 
68191
68863
  // src/commands/mission.ts
68192
- var MISSION_ID11 = /^mis_[A-Za-z0-9_-]{8,100}$/;
68864
+ var MISSION_ID12 = /^mis_[A-Za-z0-9_-]{8,100}$/;
68193
68865
  var MAX_TICKET_BYTES2 = 1e5;
68194
68866
  function coordinatorRuntimeIdentity(environment2) {
68195
68867
  const codex = [
@@ -68241,7 +68913,7 @@ function missionIdFrom(options2) {
68241
68913
  if (missionId === void 0) {
68242
68914
  return invalid15("missing required option --id", "pass --id mis_<opaque-id>");
68243
68915
  }
68244
- if (!MISSION_ID11.test(missionId)) {
68916
+ if (!MISSION_ID12.test(missionId)) {
68245
68917
  return invalid15("invalid mission ID", "pass the ID returned by mission start");
68246
68918
  }
68247
68919
  return missionId;
@@ -68254,6 +68926,11 @@ function parseMissionArgs(args) {
68254
68926
  return { kind: "help" };
68255
68927
  }
68256
68928
  const command2 = divider2 === -1 ? [] : args.slice(divider2 + 1);
68929
+ const usageCommand = parseUsageCommand(
68930
+ { subcommand, options: options2, divider: divider2 },
68931
+ { invalid: invalid15, valueAfter: valueAfter2, missionIdFrom, validateOptions: validateOptions2 }
68932
+ );
68933
+ if (usageCommand !== void 0) return usageCommand;
68257
68934
  if (subcommand === "evidence-request" || subcommand === "evidence-event") {
68258
68935
  if (divider2 !== -1) return invalid15("evidence commands do not accept a command", "remove --");
68259
68936
  const names = options2.filter((value) => value.startsWith("--"));
@@ -68493,7 +69170,7 @@ function parseMissionArgs(args) {
68493
69170
  `${PRODUCT_COMMAND} mission ${subcommand} --id <id>`
68494
69171
  );
68495
69172
  }
68496
- const optionError = validateOptions2(options2, ["--id"], ["--json"]);
69173
+ const optionError = validateOptions2(options2, ["--id"], subcommand === "inspect" ? ["--json", "--usage"] : ["--json"]);
68497
69174
  if (optionError !== void 0) {
68498
69175
  return invalid15(optionError, `${PRODUCT_COMMAND} mission ${subcommand} --help`);
68499
69176
  }
@@ -68501,6 +69178,7 @@ function parseMissionArgs(args) {
68501
69178
  if (typeof missionId !== "string") return missionId;
68502
69179
  return {
68503
69180
  kind: subcommand,
69181
+ ...subcommand === "inspect" && options2.includes("--usage") ? { usage: true } : {},
68504
69182
  missionId,
68505
69183
  json: options2.includes("--json")
68506
69184
  };
@@ -68633,6 +69311,7 @@ async function recoverStoppedMission(roots, missionId, request) {
68633
69311
  const identity2 = missionRuntimeIdentity(inspected.stream.events);
68634
69312
  const coordinator = coordinatorRuntimeIdentity(process.env);
68635
69313
  const provenanceRecovery = request.disposition.kind === "review-provenance";
69314
+ const targetedContextRecovery = request.disposition.kind === "controller-defect" && request.disposition.defect === "targeted-review-context";
68636
69315
  if (identity2 === void 0 || coordinator.attested && coordinator.runtime !== identity2.runtime || !provenanceRecovery && (!identity2.attested || !coordinator.attested)) {
68637
69316
  throw new Error("MISSION_RECOVERY_RUNTIME: observe the original native runtime before recovery");
68638
69317
  }
@@ -68686,10 +69365,10 @@ async function recoverStoppedMission(roots, missionId, request) {
68686
69365
  const provenance4 = request.disposition.kind !== "review-provenance" ? void 0 : await readRecoveryReviewBindings(workRoot, request.disposition.resolutionArtifact.path);
68687
69366
  const resolutionArtifact = provenance4?.artifact ?? (request.disposition.kind === "review-blocker" || request.disposition.kind === "command-correction" ? await recoveryResolutionArtifact(workRoot, request.disposition.resolutionArtifact.path) : void 0);
68688
69367
  const opaqueContextRecovery = request.disposition.kind === "controller-defect" && request.disposition.defect === "opaque-native-context";
68689
- const recoverySpecialists = opaqueContextRecovery || request.disposition.kind === "preparation-invocation" ? migration.plan.specialists.filter((value) => value.state === "applicable" && value.stages?.includes("pre-implementation")) : migration.plan.specialists;
68690
- const observation2 = {
68691
- ...provenance4 === void 0 || subject?.baseCommit === void 0 || subject.reviewedCommit === void 0 ? {} : {
68692
- reviewBindings: provenance4.bindings,
69368
+ const recoverySpecialists = targetedContextRecovery ? migration.plan.specialists.filter((value) => value.specialistId === "core:independent-code-reviewer") : opaqueContextRecovery || request.disposition.kind === "preparation-invocation" ? migration.plan.specialists.filter((value) => value.state === "applicable" && value.stages?.includes("pre-implementation")) : migration.plan.specialists;
69369
+ const observation3 = {
69370
+ ...provenance4 === void 0 && !targetedContextRecovery || subject?.baseCommit === void 0 || subject.reviewedCommit === void 0 ? {} : {
69371
+ ...provenance4 === void 0 ? {} : { reviewBindings: provenance4.bindings },
68693
69372
  reviewSubject: {
68694
69373
  taskId: missionId,
68695
69374
  baseCommit: subject.baseCommit,
@@ -68706,7 +69385,7 @@ async function recoverStoppedMission(roots, missionId, request) {
68706
69385
  contractVersions: Object.fromEntries(recoverySpecialists.map((value) => [value.specialistId, value.contractVersion])),
68707
69386
  ...resolutionArtifact === void 0 ? {} : { resolutionArtifact }
68708
69387
  };
68709
- const result = await recordStoppedMissionRecovery(installRoot, missionId, request, observation2);
69388
+ const result = await recordStoppedMissionRecovery(installRoot, missionId, request, observation3);
68710
69389
  return { ...result, provenance: {
68711
69390
  coreRoot,
68712
69391
  catalogHash: canonicalJsonHash(catalog),
@@ -69101,7 +69780,10 @@ function usage() {
69101
69780
  mission close --id <id> --reason interrupted|abandoned [--json]
69102
69781
  mission verify --id <id> [--shell] [--json] -- <command...>
69103
69782
  mission resume --id <id> [--json]
69104
- mission inspect --id <id> [--json]
69783
+ mission inspect --id <id> [--usage] [--json]
69784
+ mission usage-bind --id <id> --source <session-journal-id> [--json]
69785
+ mission usage-unbind --id <id> --source <session-journal-id> [--json]
69786
+ mission advisory-start --id <id> --specialist core:<role> --runtime claude|codex --context <native-id> [--json]
69105
69787
  mission archive --id <id> [--json]
69106
69788
  mission prune --older-than <days> [--apply] [--json]
69107
69789
 
@@ -69159,6 +69841,10 @@ Fix: ${parsed.fix}
69159
69841
  const root = roots.workRoot;
69160
69842
  const journal = roots.installRoot;
69161
69843
  try {
69844
+ if (parsed.kind === "usage-bind" || parsed.kind === "usage-unbind" || parsed.kind === "advisory-start") {
69845
+ process.stdout.write(await runUsageCommand(parsed, journal));
69846
+ return;
69847
+ }
69162
69848
  if (parsed.kind === "plan") {
69163
69849
  const plan2 = await planMission(root, parsed.ticketPath, void 0, "project-v1");
69164
69850
  process.stdout.write(parsed.json ? `${JSON.stringify(plan2)}
@@ -69337,11 +70023,15 @@ ${selection.promotion === void 0 ? "" : `mode ${selection.requestedMode} -> ${se
69337
70023
  const { inspected } = await inspectCurrentMission(
69338
70024
  roots,
69339
70025
  parsed.missionId,
69340
- collectKnownSecrets()
70026
+ collectKnownSecrets(),
70027
+ parsed.usage ? { quarantine: false } : {}
69341
70028
  );
70029
+ const usageReport = parsed.usage ? await loadMissionUsage(roots.installRoot, parsed.missionId, inspected.stream) : void 0;
69342
70030
  process.stdout.write(
69343
- parsed.json ? `${JSON.stringify(inspected.verdict)}
69344
- ` : `${renderInspection(inspected)}
70031
+ parsed.json ? `${JSON.stringify(usageReport === void 0 ? inspected.verdict : { ...inspected.verdict, usage: usageReport })}
70032
+ ` : `${renderInspection(inspected)}${usageReport === void 0 ? "" : `
70033
+
70034
+ ${renderMissionUsage(usageReport)}`}
69345
70035
  `
69346
70036
  );
69347
70037
  process.exitCode = missionVerdictExitCode(inspected.verdict.status);
@@ -69854,14 +70544,14 @@ function fromZap(payload) {
69854
70544
  const alerts = Array.isArray(site["alerts"]) ? site["alerts"] : [];
69855
70545
  for (const alert of alerts) {
69856
70546
  const name = text6(alert["name"], "unnamed alert");
69857
- const reference = text6(alert["alertRef"], "unknown");
70547
+ const reference2 = text6(alert["alertRef"], "unknown");
69858
70548
  findings.push({
69859
70549
  adapter: "zap-baseline",
69860
70550
  securityClass: "misconfiguration",
69861
70551
  reportedSeverity: ZAP_SEVERITY[text6(alert["riskcode"], "0")] ?? "info",
69862
- rule: reference,
70552
+ rule: reference2,
69863
70553
  summary: `${name}${host === "" ? "" : ` on ${host}`}`,
69864
- reproduction: `zap-baseline raised alert ${reference} (${name})${host === "" ? "" : ` against ${host}`}`,
70554
+ reproduction: `zap-baseline raised alert ${reference2} (${name})${host === "" ? "" : ` against ${host}`}`,
69865
70555
  remediation: text6(alert["solution"], "Read the ZAP alert reference and fix the response the scan describes.")
69866
70556
  });
69867
70557
  }