@brainervirus/workit-cursor 1.0.10 → 1.0.12

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.
@@ -7492,7 +7492,87 @@ var SCHEMA_VERSION = 1, POLICY_VERSION = "1.0.0", OPERATION_FAMILIES, uuidPatter
7492
7492
  const covers = (path) => normOuter.paths.some((base) => base === "." || path === base || path.startsWith(`${base}/`)) && !excluded(path, normOuter);
7493
7493
  const innerExcludes = (path) => innerExclusions.some((excludedPath) => excludedPath === path || path.startsWith(`${excludedPath}/`));
7494
7494
  return innerPaths.every(covers) && !normOuter.exclusions.some((excludedPath) => innerPaths.some((base) => (base === "." || excludedPath === base || excludedPath.startsWith(`${base}/`)) && !innerExcludes(excludedPath)));
7495
- }, refSchema, provenanceSchema, entrySchema = (data) => object({ id, recordedAt: utc, provenance: provenanceSchema, data }).strict(), factSchema, signalSchema, signalSet, consequenceSchema, verificationSchema, assessmentSchema, constraintSchema, intentSchema, progressSchema, dimensionSchema, policySchema, requirementSchema, policyChangeSchema, candidateSchema, evidenceSchema, evidenceEvaluationSchema, decisionSchema, findingSchema, assignmentSchema, workerReportSchema, workerSchema, ownerSchema, closureSchema, actionProgressSchema, actionProgressListSchema, runtimeSchema, taskRecordSchema, workspaceRecordSchema, capabilitySchema, requirementEvaluationSchema, taskViewSchema, taskSummarySchema, exportBundleSchema, callerSchema, base, revisions, taskId, operation = (shape) => object({ ...base, ...shape }).strict(), taskOperations, policyOperations, evidenceOperations, findingOperations, decisionOperations, workerOperations, writerOperations, stateOperations, operationSchemas, compiledOperationSchemas, success = (revisionValue, workspaceRevisionValue, data) => ({
7495
+ }, refSchema, rewriteUnknown = (value, map) => {
7496
+ if (Array.isArray(value)) {
7497
+ const out = [];
7498
+ for (const item of value) {
7499
+ const rewritten = rewriteUnknown(item, map);
7500
+ if (!rewritten.drop)
7501
+ out.push(rewritten.value);
7502
+ }
7503
+ return { drop: false, value: out };
7504
+ }
7505
+ if (typeof value === "object" && value !== null) {
7506
+ if (refSchema.safeParse(value).success) {
7507
+ const mapped = map(value);
7508
+ return mapped === null ? { drop: true } : { drop: false, value: mapped };
7509
+ }
7510
+ const out = {};
7511
+ for (const [key, item] of Object.entries(value)) {
7512
+ const rewritten = rewriteUnknown(item, map);
7513
+ out[key] = rewritten.drop ? null : rewritten.value;
7514
+ }
7515
+ return { drop: false, value: out };
7516
+ }
7517
+ return { drop: false, value };
7518
+ }, rewriteNode = (value, schema, map) => {
7519
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && refSchema.safeParse(value).success) {
7520
+ const mapped = map(value);
7521
+ return mapped === null ? { drop: true } : { drop: false, value: mapped };
7522
+ }
7523
+ let node = schema;
7524
+ while (node instanceof ZodNullable || node instanceof ZodOptional || node instanceof ZodDefault) {
7525
+ node = node.unwrap();
7526
+ }
7527
+ if (node === refSchema) {
7528
+ if (!refSchema.safeParse(value).success)
7529
+ return { drop: false, value };
7530
+ const mapped = map(value);
7531
+ return mapped === null ? { drop: true } : { drop: false, value: mapped };
7532
+ }
7533
+ if (node instanceof ZodArray) {
7534
+ if (!Array.isArray(value))
7535
+ return { drop: false, value };
7536
+ const out = [];
7537
+ for (const item of value) {
7538
+ const rewritten = rewriteNode(item, node.element, map);
7539
+ if (!rewritten.drop)
7540
+ out.push(rewritten.value);
7541
+ }
7542
+ return { drop: false, value: out };
7543
+ }
7544
+ if (node instanceof ZodObject) {
7545
+ if (typeof value !== "object" || value === null || Array.isArray(value))
7546
+ return { drop: false, value };
7547
+ const shape = node.shape;
7548
+ const record = value;
7549
+ const out = {};
7550
+ for (const [key, item] of Object.entries(record)) {
7551
+ if (!(key in shape)) {
7552
+ const scrubbed = rewriteUnknown(item, map);
7553
+ out[key] = scrubbed.drop ? null : scrubbed.value;
7554
+ continue;
7555
+ }
7556
+ const child = shape[key];
7557
+ const rewritten = rewriteNode(item, child, map);
7558
+ if (rewritten.drop) {
7559
+ if (child instanceof ZodOptional || child instanceof ZodDefault)
7560
+ continue;
7561
+ if (child instanceof ZodNullable) {
7562
+ out[key] = null;
7563
+ continue;
7564
+ }
7565
+ return { drop: true };
7566
+ }
7567
+ out[key] = rewritten.value;
7568
+ }
7569
+ return { drop: false, value: out };
7570
+ }
7571
+ return { drop: false, value };
7572
+ }, rewriteRecordRefs = (value, schema, map) => {
7573
+ const rewritten = rewriteNode(value, schema, map);
7574
+ return rewritten.drop ? null : rewritten.value;
7575
+ }, provenanceSchema, entrySchema = (data) => object({ id, recordedAt: utc, provenance: provenanceSchema, data }).strict(), factSchema, signalSchema, signalSet, consequenceSchema, verificationSchema, assessmentSchema, constraintSchema, intentSchema, progressSchema, dimensionSchema, policySchema, requirementSchema, policyChangeSchema, candidateSchema, evidenceSchema, evidenceEvaluationSchema, decisionSchema, findingSchema, assignmentSchema, workerReportSchema, workerSchema, ownerSchema, closureSchema, actionProgressSchema, actionProgressListSchema, runtimeSchema, taskRecordSchema, workspaceRecordSchema, capabilitySchema, requirementEvaluationSchema, taskViewSchema, taskSummarySchema, exportBundleSchema, callerSchema, base, revisions, taskId, operation = (shape) => object({ ...base, ...shape }).strict(), taskOperations, policyOperations, evidenceOperations, findingOperations, decisionOperations, workerOperations, writerOperations, stateOperations, operationSchemas, compiledOperationSchemas, success = (revisionValue, workspaceRevisionValue, data) => ({
7496
7576
  ok: true,
7497
7577
  schemaVersion: 1,
7498
7578
  revision: revisionValue,
@@ -7795,10 +7875,11 @@ var init_task_contract = __esm(() => {
7795
7875
  presented: text,
7796
7876
  approvedContent: text,
7797
7877
  displayed: text.optional(),
7798
- contentRefs: array(refSchema)
7878
+ contentRefs: array(refSchema),
7879
+ statedChoice: object({ ref: text, text }).strict().optional()
7799
7880
  }).strict(),
7800
7881
  digest,
7801
- response: _enum(["approved", "rejected"]),
7882
+ response: _enum(["approved", "rejected", "stated"]),
7802
7883
  requirementIds: array(digest),
7803
7884
  revoked: object({ at: utc, reason: text }).strict().nullable(),
7804
7885
  consumption: object({
@@ -9074,11 +9155,11 @@ class TaskStore {
9074
9155
  return workspace;
9075
9156
  if (!workspace.data)
9076
9157
  return failure("not_found", "workspace not found");
9077
- const expectedTaskRevision = input.expectedTaskRevision ?? input.expectedRevision;
9078
- if (!expectedTaskRevision)
9158
+ const expected = input.expectedRevision;
9159
+ if (!expected)
9079
9160
  return failure("invalid_input", "task revision is required");
9080
- if (task.data.revision !== expectedTaskRevision)
9081
- return this.conflict(expectedTaskRevision, task.data.revision);
9161
+ if (task.data.revision !== expected)
9162
+ return this.conflict(expected, task.data.revision);
9082
9163
  if (workspace.data.revision !== input.expectedWorkspaceRevision)
9083
9164
  return this.conflict(input.expectedWorkspaceRevision, workspace.data.revision);
9084
9165
  const previousWorkspaceBytes = this.snapshotBytes(this.workspacePath);
@@ -9704,7 +9785,7 @@ var same = (left, right) => {
9704
9785
  } catch {
9705
9786
  return false;
9706
9787
  }
9707
- }, UNCERTAIN_WORKER_STATES, isUncertainWorker = (state) => UNCERTAIN_WORKER_STATES.includes(state), callerSession = (caller) => caller.session ?? { kind: "host", host: caller.host, handle: caller.actor }, validPath = (value) => typeof value === "string" && value.length > 0 && ![...value].some((char) => {
9788
+ }, UNCERTAIN_WORKER_STATES, isUncertainWorker = (state) => UNCERTAIN_WORKER_STATES.includes(state), workerBlocksTransition = (transition, state) => transition === "pause" ? false : isUncertainWorker(state), callerSession = (caller) => caller.session ?? { kind: "host", host: caller.host, handle: caller.actor }, validPath = (value) => typeof value === "string" && value.length > 0 && ![...value].some((char) => {
9708
9789
  const code = char.charCodeAt(0);
9709
9790
  return code < 32 || code === 127;
9710
9791
  }) && !value.split(/[\\/]/).includes(".."), callerValue = (value) => ({ host: value.host, actor: value.actor }), workerIdOf = (value) => value.workerId ?? null;
@@ -9999,6 +10080,33 @@ var verifiedAuthorities, trustedAuthority = (kind, provenance, expected, binding
9999
10080
  const token = {};
10000
10081
  verifiedAuthorities.set(token, { kind, provenance, ...expected, ...binding, caller });
10001
10082
  return token;
10083
+ }, chainStepKey = (step) => step.kind === "commit" ? step.message : step.kind === "branch" ? `branch:${step.target}` : "pr", isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value), normalizeChainSteps = (steps) => {
10084
+ if (!Array.isArray(steps) || steps.length === 0 || steps.length > 32)
10085
+ return null;
10086
+ const normalized = [];
10087
+ for (const step of steps) {
10088
+ if (typeof step === "string") {
10089
+ if (!step.trim())
10090
+ return null;
10091
+ normalized.push({ kind: "commit", message: step });
10092
+ continue;
10093
+ }
10094
+ if (!isRecord(step))
10095
+ return null;
10096
+ if (typeof step.branch === "string" && step.branch.trim() && Object.keys(step).length === 1) {
10097
+ normalized.push({ kind: "branch", target: step.branch });
10098
+ continue;
10099
+ }
10100
+ if (step.pr === true && Object.keys(step).length === 1) {
10101
+ normalized.push({ kind: "pr" });
10102
+ continue;
10103
+ }
10104
+ return null;
10105
+ }
10106
+ const keys = normalized.map(chainStepKey);
10107
+ if (new Set(keys).size !== keys.length)
10108
+ return null;
10109
+ return normalized;
10002
10110
  }, scopeEqual = (left, right) => canonicalJson(left) === canonicalJson(right), parseSteps = (content) => {
10003
10111
  let value;
10004
10112
  try {
@@ -10009,7 +10117,10 @@ var verifiedAuthorities, trustedAuthority = (kind, provenance, expected, binding
10009
10117
  if (typeof value !== "object" || value === null || !("steps" in value))
10010
10118
  return [];
10011
10119
  const steps = value.steps;
10012
- return Array.isArray(steps) && steps.every((step) => typeof step === "string") ? steps : null;
10120
+ if (!Array.isArray(steps))
10121
+ return null;
10122
+ const normalized = normalizeChainSteps(steps);
10123
+ return normalized;
10013
10124
  }, decisionMatches = (entry, purpose, binding) => {
10014
10125
  const decision = entry.data;
10015
10126
  return binding.taskId === decision.binding.taskId && binding.workspaceId === decision.binding.workspaceId && decision.purpose === purpose && decision.response === "approved" && decision.revoked === null && (purpose !== "action" || decision.consumption === null) && decision.digest === decisionDigest(decision) && scopeEqual(decision.binding.scope, binding.scope) && canonicalJson(decision.binding) === canonicalJson(binding);
@@ -10179,14 +10290,12 @@ var verifiedAuthorities, trustedAuthority = (kind, provenance, expected, binding
10179
10290
  return content;
10180
10291
  const requestedSteps = parseSteps(decision.binding.approvedContent);
10181
10292
  if (requestedSteps === null)
10182
- return failure("invalid_input", "bounded action steps must be a string array");
10183
- if (input.steps && canonicalJson(input.steps) !== canonicalJson(requestedSteps))
10293
+ return failure("invalid_input", "bounded action steps must be a unique non-empty array");
10294
+ if (input.steps && canonicalJson(input.steps) !== canonicalJson(requestedSteps.map(chainStepKey)))
10184
10295
  return failure("permission_denied", "bounded action steps do not match approved content");
10185
- if (requestedSteps.some((step) => !step || typeof step !== "string") || new Set(requestedSteps).size !== requestedSteps.length)
10186
- return failure("invalid_input", "bounded action steps must be unique and non-empty");
10187
10296
  const stored = task.actionProgress?.find((item) => item.decisionId === input.decisionId);
10188
- const workflow = stored ? { steps: stored.steps, completed: stored.completedSteps } : { steps: requestedSteps, completed: [] };
10189
- if (workflow.steps.length && requestedSteps.length && canonicalJson(workflow.steps) !== canonicalJson(requestedSteps))
10297
+ const workflow = stored ? { steps: stored.steps, completed: stored.completedSteps } : { steps: requestedSteps.map(chainStepKey), completed: [] };
10298
+ if (workflow.steps.length && requestedSteps.length && canonicalJson(workflow.steps) !== canonicalJson(requestedSteps.map(chainStepKey)))
10190
10299
  return failure("permission_denied", "bounded action scope changed");
10191
10300
  return success(null, null, { entry, workflow });
10192
10301
  }, bindingCovers, verifyDecisionContent;
@@ -10354,7 +10463,7 @@ function evaluateRequirements(task, workspace, capabilities, candidate, checkout
10354
10463
  return (task.policy?.requirements ?? []).map((requirement) => {
10355
10464
  const related = task.evidence.map((entry, index) => ({ entry, evaluation: evidence[index] })).filter(({ entry }) => entry.data.requirementIds.includes(requirement.id));
10356
10465
  const passed = related.filter(({ entry, evaluation }) => {
10357
- if (!evidenceMatchesRequirement(evaluation.status, entry.data.kind, requirement.dimension))
10466
+ if (!evidenceMatchesRequirement(evaluation.status, entry.data.kind, requirement.dimension, requirement.ruleId))
10358
10467
  return false;
10359
10468
  if ((entry.data.kind === "check" || entry.data.kind === "review") && (!entry.data.beforeCandidateId || !entry.data.candidateId || entry.data.beforeCandidateId !== entry.data.candidateId))
10360
10469
  return false;
@@ -10362,11 +10471,12 @@ function evaluateRequirements(task, workspace, capabilities, candidate, checkout
10362
10471
  return true;
10363
10472
  const reviewSession = sessionFromRef(entry.data.reviewContext);
10364
10473
  const sameImplementation = sameSession(reviewSession, task.intent.provenance.session);
10365
- const sameEvidenceSession = task.evidence.some((other) => other.id !== entry.id && other.data.kind === "review" && sameSession(reviewSession, other.provenance.session));
10474
+ const sameEvidenceSession = related.some(({ entry: other }) => other.id !== entry.id && other.data.kind === "review" && other.data.candidateId !== null && other.data.candidateId === entry.data.candidateId && sameSession(reviewSession, other.provenance.session));
10366
10475
  return entry.data.kind === "review" && reviewSession !== null && sameSession(reviewSession, entry.provenance.session) && (requirement.ruleId === "self-review" || !sameImplementation && !sameEvidenceSession);
10367
10476
  });
10368
10477
  if (passed.length) {
10369
- const withRed = requirement.dimension === "testing" ? passed.filter(({ entry }) => related.some((other) => other.entry.data.kind === "check" && other.evaluation.status === "failed" && other.entry.data.requirementIds.includes(requirement.id) && other.entry.recordedAt <= entry.recordedAt)) : passed;
10478
+ const currentId = candidate?.id ?? null;
10479
+ const withRed = requirement.dimension === "testing" ? passed.filter(({ entry }) => related.some((other) => other.entry.data.kind === "check" && other.evaluation.status === "failed" && other.entry.data.requirementIds.includes(requirement.id) && other.entry.recordedAt <= entry.recordedAt) || related.some((baseline) => baseline.entry.id !== entry.id && baseline.entry.data.kind === "check" && baseline.entry.data.result === "passed" && baseline.entry.data.candidateId !== null && currentId !== null && baseline.entry.data.candidateId !== currentId)) : passed;
10370
10480
  if (withRed.length)
10371
10481
  return {
10372
10482
  requirementId: requirement.id,
@@ -10403,7 +10513,7 @@ function evaluateRequirements(task, workspace, capabilities, candidate, checkout
10403
10513
  status: "satisfied",
10404
10514
  evidenceIds: [],
10405
10515
  decisionIds: decisions.map((decision) => decision.id),
10406
- reason: "an applicable approved decision satisfies the requirement"
10516
+ reason: "an applicable approved or stated decision satisfies the requirement"
10407
10517
  };
10408
10518
  const limitations = requirement.acceptanceAllowed ? applicableDecision2(task, workspace, requirement, checkoutRoot) : [];
10409
10519
  if (limitations.length)
@@ -10415,6 +10525,14 @@ function evaluateRequirements(task, workspace, capabilities, candidate, checkout
10415
10525
  reason: "an applicable approved limitation permits the missing evidence"
10416
10526
  };
10417
10527
  const unavailable = capabilities.some((capability) => capability.assurance === "unavailable" && (capability.name === requirement.dimension || capability.surface === requirement.dimension));
10528
+ if (!unavailable && related.length > 0 && !passed.length)
10529
+ return {
10530
+ requirementId: requirement.id,
10531
+ status: "unsatisfied",
10532
+ evidenceIds: related.map(({ entry }) => entry.id),
10533
+ decisionIds: [],
10534
+ reason: `no passing evidence (needs kind:${expectedKinds(requirement.dimension, requirement.ruleId)})`
10535
+ };
10418
10536
  return {
10419
10537
  requirementId: requirement.id,
10420
10538
  status: unavailable ? "unavailable" : "unsatisfied",
@@ -10439,7 +10557,13 @@ function evaluateClosure(requestedOutcome, view) {
10439
10557
  if (entry.data.disposition === "fixed") {
10440
10558
  const verified = entry.data.resolution?.evidenceIds.some((id) => {
10441
10559
  const evidence = view.task.evidence.find((item) => item.id === id);
10442
- return evidenceById.get(id) === "passed" && (evidence?.data.kind === "check" || evidence?.data.kind === "review");
10560
+ if (!evidence)
10561
+ return false;
10562
+ return findingVerificationPasses(entry.data.candidateId, {
10563
+ kind: evidence.data.kind,
10564
+ candidateId: evidence.data.candidateId,
10565
+ status: evidenceById.get(id) ?? "missing"
10566
+ });
10443
10567
  });
10444
10568
  if (!verified)
10445
10569
  return failure("requirements_unsatisfied", "fixed findings require current verification");
@@ -10455,7 +10579,12 @@ function evaluateClosure(requestedOutcome, view) {
10455
10579
  }
10456
10580
  }
10457
10581
  }
10458
- const blocking = evaluations.filter((item) => item.status === "unsatisfied" || item.status === "unavailable");
10582
+ const blocking = evaluations.filter((item) => {
10583
+ if (item.status !== "unsatisfied" && item.status !== "unavailable")
10584
+ return false;
10585
+ const requirement = view.task.policy?.requirements.find((candidate) => candidate.id === item.requirementId);
10586
+ return !requirement || requirement.before === "close";
10587
+ });
10459
10588
  if (requestedOutcome !== "stopped" && blocking.length)
10460
10589
  return failure("requirements_unsatisfied", "applicable requirements are unsatisfied", {
10461
10590
  requirementIds: blocking.map((item) => item.requirementId),
@@ -10611,11 +10740,23 @@ var digestBytes3 = (value) => createHash4("sha256").update(value).digest("hex"),
10611
10740
  }, sameSession = (left, right) => {
10612
10741
  const other = sessionFromRef(right);
10613
10742
  return left !== null && other !== null && left.host === other.host && left.handle === other.handle;
10614
- }, evidenceScopes = (task, ids) => (task.policy?.requirements ?? []).filter((requirement) => ids.includes(requirement.id)).map((requirement) => requirement.scope), scopeCovers2, applicableDecision2 = (task, workspace, requirement, checkoutRoot) => task.decisions.filter((entry) => entry.provenance.kind !== "imported").map((entry) => entry.data).filter((decision) => decision.purpose === "limitation" && decision.response === "approved" && decision.revoked === null && decision.binding.taskId === task.id && decision.binding.workspaceId === workspace.id && decision.requirementIds.includes(requirement.id) && decision.binding.scope && scopeCovers2(decision.binding.scope, requirement.scope) && decision.digest === decisionDigest(decision) && (checkoutRoot ? verifyDecisionContentAtRoot(checkoutRoot, decision.binding).ok : decision.binding.contentRefs.every((reference) => reference.kind !== "file"))), applicableRequirementDecision = (task, workspace, requirement, checkoutRoot) => task.decisions.filter(({ data, provenance }) => provenance.kind !== "imported" && data.purpose !== "limitation" && data.response === "approved" && data.revoked === null && data.binding.taskId === task.id && data.binding.workspaceId === workspace.id && data.requirementIds.includes(requirement.id) && scopeCovers2(data.binding.scope, requirement.scope) && data.digest === decisionDigest(data) && (checkoutRoot ? verifyDecisionContentAtRoot(checkoutRoot, data.binding).ok : data.binding.contentRefs.every((reference) => reference.kind !== "file"))).map(({ id }) => ({ id })), evidenceMatchesRequirement = (kind, evidenceKind, dimension) => {
10743
+ }, evidenceScopes = (task, ids) => (task.policy?.requirements ?? []).filter((requirement) => ids.includes(requirement.id)).map((requirement) => requirement.scope), scopeCovers2, checkPin = (assignment, beforeCandidateId, candidateId) => {
10744
+ const pin = assignment.candidateId ?? null;
10745
+ if (pin === null)
10746
+ return true;
10747
+ return (beforeCandidateId ?? null) === pin || (candidateId ?? null) === pin;
10748
+ }, resolveBinding = (evidence, pin, currentCandidateId) => {
10749
+ const bound = evidence.kind === "check" || evidence.kind === "review";
10750
+ const fallback = bound ? pin ?? currentCandidateId : null;
10751
+ return {
10752
+ beforeCandidateId: evidence.beforeCandidateId ?? fallback,
10753
+ candidateId: evidence.candidateId ?? fallback
10754
+ };
10755
+ }, findingVerificationPasses = (findingCandidateId, evidence) => evidence.status === "passed" && (evidence.kind === "check" || evidence.kind === "review") && ((findingCandidateId ?? null) === null || evidence.candidateId === findingCandidateId), applicableDecision2 = (task, workspace, requirement, checkoutRoot) => task.decisions.filter((entry) => entry.provenance.kind !== "imported").map((entry) => entry.data).filter((decision) => decision.purpose === "limitation" && decision.response === "approved" && decision.revoked === null && decision.binding.taskId === task.id && decision.binding.workspaceId === workspace.id && decision.requirementIds.includes(requirement.id) && decision.binding.scope && scopeCovers2(decision.binding.scope, requirement.scope) && decision.digest === decisionDigest(decision) && (checkoutRoot ? verifyDecisionContentAtRoot(checkoutRoot, decision.binding).ok : decision.binding.contentRefs.every((reference) => reference.kind !== "file"))), applicableRequirementDecision = (task, workspace, requirement, checkoutRoot) => task.decisions.filter(({ data, provenance }) => provenance.kind !== "imported" && data.purpose !== "limitation" && (data.response === "approved" || data.response === "stated") && data.revoked === null && data.binding.taskId === task.id && data.binding.workspaceId === workspace.id && data.requirementIds.includes(requirement.id) && scopeCovers2(data.binding.scope, requirement.scope) && data.digest === decisionDigest(data) && (checkoutRoot ? verifyDecisionContentAtRoot(checkoutRoot, data.binding).ok : data.binding.contentRefs.every((reference) => reference.kind !== "file"))).map(({ id }) => ({ id })), evidenceMatchesRequirement = (kind, evidenceKind, dimension, ruleId) => {
10615
10756
  if (kind !== "passed")
10616
10757
  return false;
10617
10758
  if (dimension === "testing" || dimension === "verification")
10618
- return evidenceKind === "check";
10759
+ return evidenceKind === "check" || ruleId === "pre-pr-cleanup" && evidenceKind === "artifact";
10619
10760
  if (dimension === "review")
10620
10761
  return evidenceKind === "review";
10621
10762
  if (dimension === "investigation" || dimension === "challenge")
@@ -10623,6 +10764,20 @@ var digestBytes3 = (value) => createHash4("sha256").update(value).digest("hex"),
10623
10764
  if (dimension === "artifacts" || dimension === "continuity")
10624
10765
  return evidenceKind === "artifact";
10625
10766
  return false;
10767
+ }, expectedKinds = (dimension, ruleId) => {
10768
+ if (dimension === "testing")
10769
+ return "check";
10770
+ if (dimension === "verification")
10771
+ return ruleId === "pre-pr-cleanup" ? "check or artifact" : "check";
10772
+ if (dimension === "review")
10773
+ return "review";
10774
+ if (dimension === "investigation" || dimension === "challenge")
10775
+ return "investigation";
10776
+ if (dimension === "artifacts" || dimension === "continuity")
10777
+ return "artifact";
10778
+ if (dimension === "decisions")
10779
+ return "decision";
10780
+ return "worker report";
10626
10781
  };
10627
10782
  var init_task_evaluation = __esm(() => {
10628
10783
  init_task_contract();
@@ -10633,7 +10788,7 @@ var init_task_evaluation = __esm(() => {
10633
10788
  // packages/workit-core/src/core/methods.ts
10634
10789
  function selectMethods(policy, capabilities) {
10635
10790
  return Object.entries(METHODS).flatMap(([id, definition]) => {
10636
- const requirements = policy.requirements.filter((requirement) => methodMatches(id, definition, requirement));
10791
+ const requirements = policy.requirements.filter((requirement) => methodMatches(definition, requirement));
10637
10792
  if (requirements.length === 0)
10638
10793
  return [];
10639
10794
  const capability = assuranceFor(id, definition, capabilities);
@@ -10646,7 +10801,7 @@ function selectMethods(policy, capabilities) {
10646
10801
  return [{ id, reason: reasons.join("; "), assurance: capability.assurance }];
10647
10802
  });
10648
10803
  }
10649
- var METHODS, methodMatches = (id, definition, requirement) => definition.dimensions?.includes(requirement.dimension) === true && !(id === "workit-review" && requirement.ruleId === "self-review") || definition.ruleIds?.includes(requirement.ruleId) === true, assuranceFor = (id, definition, capabilities) => {
10804
+ var METHODS, methodMatches = (definition, requirement) => definition.dimensions?.includes(requirement.dimension) === true || definition.ruleIds?.includes(requirement.ruleId) === true, assuranceFor = (id, definition, capabilities) => {
10650
10805
  const keys = new Set([
10651
10806
  id,
10652
10807
  ...definition.dimensions ?? [],
@@ -10720,12 +10875,12 @@ act from memory of it.
10720
10875
  var init_methods = __esm(() => {
10721
10876
  METHODS = {
10722
10877
  "workit-challenge": { dimensions: ["challenge", "decisions"] },
10723
- "workit-behavioral-tdd": { dimensions: ["testing"] },
10724
- "workit-review": { dimensions: ["review"], ruleIds: ["fresh-context-review"] },
10878
+ "workit-behavioral-tdd": { dimensions: ["testing"], ruleIds: ["mechanical-existing-checks"] },
10879
+ "workit-review": { dimensions: ["review"], ruleIds: ["fresh-context-review", "self-review"] },
10725
10880
  "workit-plan": { dimensions: ["artifacts", "continuity"] },
10726
10881
  "workit-implement": { dimensions: ["delegation"] },
10727
- "workit-debug": { ruleIds: ["root-cause-investigation"] },
10728
- "workit-handoff": { ruleIds: ["durable-handoff"] },
10882
+ "workit-debug": {},
10883
+ "workit-handoff": {},
10729
10884
  "workit-deslop": { ruleIds: ["pre-pr-cleanup"] }
10730
10885
  };
10731
10886
  });
@@ -10832,12 +10987,70 @@ var init_task_context = __esm(() => {
10832
10987
  });
10833
10988
 
10834
10989
  // packages/workit-core/src/core/route-intent.ts
10835
- var init_route_intent = () => {};
10990
+ var init_route_intent = __esm(() => {
10991
+ init_task_store();
10992
+ });
10993
+
10994
+ // packages/workit-core/src/core/git.ts
10995
+ var init_git = () => {};
10996
+
10997
+ // packages/workit-core/src/core/boundary.ts
10998
+ var init_boundary = () => {};
10999
+
11000
+ // packages/workit-core/src/core/config.ts
11001
+ var PRESETS, DEFAULTS;
11002
+ var init_config = __esm(() => {
11003
+ init_boundary();
11004
+ PRESETS = {
11005
+ gitflow: {
11006
+ allowed: ["feature/*", "bugfix/*", "hotfix/*", "release/*"],
11007
+ protected: ["main", "develop", "master", "prod", "production"]
11008
+ },
11009
+ "github-flow": { allowed: ["*"], protected: ["main"] },
11010
+ "trunk-based": { allowed: ["*"], protected: ["main"] },
11011
+ custom: { allowed: [], protected: [] }
11012
+ };
11013
+ DEFAULTS = {
11014
+ locale: "en",
11015
+ localeOptions: ["en", "es-CL", "es-MX", "es-AR", "pt-BR"],
11016
+ timezone: "America/Santiago",
11017
+ branchPolicy: {
11018
+ preset: "gitflow",
11019
+ allowed: [...PRESETS.gitflow.allowed],
11020
+ protected: [...PRESETS.gitflow.protected]
11021
+ },
11022
+ commitPolicy: { preset: "conventional" }
11023
+ };
11024
+ });
11025
+
11026
+ // packages/workit-core/src/core/workspaces.ts
11027
+ var init_workspaces = __esm(() => {
11028
+ init_config();
11029
+ });
11030
+
11031
+ // packages/workit-core/src/core/vcs-config.ts
11032
+ var init_vcs_config = __esm(() => {
11033
+ init_config();
11034
+ init_workspaces();
11035
+ init_branch();
11036
+ });
11037
+
11038
+ // packages/workit-core/src/core/branch.ts
11039
+ var init_branch = __esm(() => {
11040
+ init_git();
11041
+ init_config();
11042
+ init_workspaces();
11043
+ init_vcs_config();
11044
+ });
11045
+
11046
+ // packages/workit-core/src/core/runtime-identity.ts
11047
+ var init_runtime_identity = () => {};
10836
11048
 
10837
11049
  // packages/workit-core/src/core/external-action.ts
10838
11050
  var externalActionSchema;
10839
11051
  var init_external_action = __esm(() => {
10840
11052
  init_task_contract();
11053
+ init_authority();
10841
11054
  init_zod();
10842
11055
  externalActionSchema = discriminatedUnion("operation", [
10843
11056
  object({
@@ -11311,7 +11524,7 @@ class WorkitCore {
11311
11524
  activeWorkerBlocker(task, workspace) {
11312
11525
  if (workspace.writer)
11313
11526
  return failure("recovery_required", "writer ownership must be released first");
11314
- if (task.workers.some((entry) => isUncertainWorker(entry.data.state)))
11527
+ if (task.workers.some((entry) => workerBlocksTransition("close", entry.data.state)))
11315
11528
  return failure("recovery_required", "worker state requires reconciliation");
11316
11529
  return null;
11317
11530
  }
@@ -11557,37 +11770,33 @@ class WorkitCore {
11557
11770
  const currentCandidate = captureCandidate(this.store.root, task.data.intent.data.scope, environment());
11558
11771
  if (!currentCandidate.ok)
11559
11772
  return currentCandidate;
11560
- if (evidence.kind === "check" || evidence.kind === "review") {
11561
- evidence.beforeCandidateId ??= currentCandidate.data.id;
11562
- evidence.candidateId ??= currentCandidate.data.id;
11563
- } else {
11564
- evidence.beforeCandidateId ??= null;
11565
- evidence.candidateId ??= null;
11566
- }
11773
+ const pin = helper && helper.ok ? helper.data.data.assignment.candidateId : null;
11774
+ const bound = resolveBinding(evidence, pin, currentCandidate.data.id);
11567
11775
  if (helper?.ok) {
11568
11776
  const assignment = helper.data.data.assignment;
11569
- if (evidence.requirementIds.some((id) => !assignment.requirementIds.includes(id)) || assignment.candidateId !== null && evidence.candidateId !== assignment.candidateId && evidence.beforeCandidateId !== assignment.candidateId || !refsWithinScope(evidence.refs, assignment.scope) || !refsWithinScope(evidence.refs, task.data.intent.data.scope))
11777
+ if (evidence.requirementIds.some((id) => !assignment.requirementIds.includes(id)) || !checkPin(assignment, bound.beforeCandidateId, bound.candidateId) || !refsWithinScope(evidence.refs, assignment.scope) || !refsWithinScope(evidence.refs, task.data.intent.data.scope))
11570
11778
  return failure("permission_denied", "evidence is outside the worker assignment");
11571
11779
  }
11572
11780
  const knownCandidates = new Set(task.data.candidates.map((candidate) => candidate.id));
11573
- for (const candidateId of [evidence.beforeCandidateId, evidence.candidateId]) {
11781
+ for (const candidateId of [bound.beforeCandidateId, bound.candidateId]) {
11574
11782
  if (candidateId && candidateId !== currentCandidate.data.id && !knownCandidates.has(candidateId))
11575
11783
  return failure("invalid_input", "evidence candidate is not a captured candidate");
11576
11784
  }
11785
+ const boundEvidence = { ...evidence, ...bound };
11577
11786
  const changed = this.store.mutateTask(task.data.id, input.expectedRevision, (current, mutation) => {
11578
11787
  const candidates = current.candidates.some((item) => item.id === currentCandidate.data.id) ? current.candidates : [...current.candidates, currentCandidate.data];
11579
11788
  const entry = {
11580
11789
  id: newId(),
11581
11790
  recordedAt: mutation.now,
11582
11791
  provenance: provenance(this.context, "agent_reported"),
11583
- data: evidence
11792
+ data: boundEvidence
11584
11793
  };
11585
11794
  return success(mutation.revision, null, {
11586
11795
  ...current,
11587
11796
  candidates,
11588
11797
  evidence: [...current.evidence, entry],
11589
11798
  findings: current.findings.map((finding) => {
11590
- if (finding.data.disposition === "open" || evidence.result === "skipped")
11799
+ if (finding.data.disposition === "open" || boundEvidence.result === "skipped")
11591
11800
  return finding;
11592
11801
  if (finding.data.disposition !== "fixed")
11593
11802
  return finding;
@@ -11596,8 +11805,12 @@ class WorkitCore {
11596
11805
  item.evidenceId,
11597
11806
  item.status
11598
11807
  ]));
11599
- const verified = withEntry.evidence.some((item) => statuses.get(item.id) === "passed" && (item.data.kind === "check" || item.data.kind === "review") && (finding.data.candidateId === null || item.data.candidateId === finding.data.candidateId));
11600
- const contradicted = evidence.result === "failed" && finding.data.refs.some((left) => evidence.refs.some((right) => JSON.stringify(left) === JSON.stringify(right)));
11808
+ const verified = withEntry.evidence.some((item) => findingVerificationPasses(finding.data.candidateId, {
11809
+ kind: item.data.kind,
11810
+ candidateId: item.data.candidateId,
11811
+ status: statuses.get(item.id) ?? "missing"
11812
+ }));
11813
+ const contradicted = boundEvidence.result === "failed" && finding.data.refs.some((left) => boundEvidence.refs.some((right) => sameValue(left, right)));
11601
11814
  return verified && !contradicted ? finding : { ...finding, data: { ...finding.data, disposition: "open", resolution: null } };
11602
11815
  })
11603
11816
  });
@@ -11622,7 +11835,12 @@ class WorkitCore {
11622
11835
  const input = parsed.data;
11623
11836
  if (nativeRequired && input.action !== "record")
11624
11837
  return failure("permission_denied", "native observation is only valid for recording decisions");
11625
- if (nativeRequired && nativeObservation === undefined)
11838
+ const stated = input.action === "record" && input.response === "stated";
11839
+ if (stated && input.purpose === "action")
11840
+ return failure("permission_denied", "stated choices cannot authorize mutating actions");
11841
+ if (stated && !input.binding?.statedChoice)
11842
+ return failure("invalid_input", "stated choices require binding.statedChoice");
11843
+ if (nativeRequired && nativeObservation === undefined && !stated)
11626
11844
  return failure("permission_denied", "native decision observation is required");
11627
11845
  const task = this.store.readTask(input.taskId);
11628
11846
  if (!task.ok)
@@ -11655,7 +11873,7 @@ class WorkitCore {
11655
11873
  consumption: null
11656
11874
  };
11657
11875
  const data = { ...base, digest: decisionDigest(base) };
11658
- const native = nativeRequired ? verifyNativeDecision(this.context.nativeAuthority, {
11876
+ const native = nativeRequired && !stated ? verifyNativeDecision(this.context.nativeAuthority, {
11659
11877
  observation: nativeObservation,
11660
11878
  expected: {
11661
11879
  taskId: task.data.id,
@@ -11750,7 +11968,7 @@ class WorkitCore {
11750
11968
  if (input.action === "record") {
11751
11969
  if (helper?.ok) {
11752
11970
  const assignment = helper.data.data.assignment;
11753
- if (!bindingCovers(assignment.scope, input.scope) || !bindingCovers(task.data.intent.data.scope, input.scope) || assignment.candidateId !== null && input.candidateId !== assignment.candidateId || !refsWithinScope(input.refs, assignment.scope) || !refsWithinScope(input.refs, task.data.intent.data.scope))
11971
+ if (!bindingCovers(assignment.scope, input.scope) || !bindingCovers(task.data.intent.data.scope, input.scope) || !checkPin(assignment, null, input.candidateId ?? null) || !refsWithinScope(input.refs, assignment.scope) || !refsWithinScope(input.refs, task.data.intent.data.scope))
11754
11972
  return failure("permission_denied", "finding is outside the worker assignment");
11755
11973
  }
11756
11974
  if (input.candidateId && !task.data.candidates.some((candidate) => candidate.id === input.candidateId))
@@ -11797,7 +12015,11 @@ class WorkitCore {
11797
12015
  const evaluations = evaluateEvidence(task.data, current.data);
11798
12016
  const verified = evidence.some((entry) => {
11799
12017
  const evaluation = evaluations.find((item) => item.evidenceId === entry.id);
11800
- return evaluation?.status === "passed" && (entry.data.kind === "check" || entry.data.kind === "review") && (finding.data.candidateId === null || entry.data.candidateId === finding.data.candidateId);
12018
+ return findingVerificationPasses(finding.data.candidateId, {
12019
+ kind: entry.data.kind,
12020
+ candidateId: entry.data.candidateId,
12021
+ status: evaluation?.status ?? "missing"
12022
+ });
11801
12023
  });
11802
12024
  if (!verified)
11803
12025
  return failure("permission_denied", "fixed findings require passing verification evidence");
@@ -11809,7 +12031,7 @@ class WorkitCore {
11809
12031
  if (entry.data.result === "missing" || entry.data.result === "skipped")
11810
12032
  return false;
11811
12033
  const candidateMatches = finding.data.candidateId === null ? entry.data.candidateId === null : entry.data.candidateId === finding.data.candidateId || entry.data.beforeCandidateId === finding.data.candidateId;
11812
- const referenceMatches = finding.data.refs.some((left) => entry.data.refs.some((right) => JSON.stringify(left) === JSON.stringify(right)));
12034
+ const referenceMatches = finding.data.refs.some((left) => entry.data.refs.some((right) => sameValue(left, right)));
11813
12035
  return candidateMatches && (referenceMatches || entry.data.claim === finding.data.claim);
11814
12036
  });
11815
12037
  if (!relevant)
@@ -11887,7 +12109,7 @@ class WorkitCore {
11887
12109
  const workerId = newId();
11888
12110
  const changed = this.store.mutateTaskAndWorkspace({
11889
12111
  taskId: task.data.id,
11890
- expectedTaskRevision: input.expectedRevision,
12112
+ expectedRevision: input.expectedRevision,
11891
12113
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
11892
12114
  now: trustedNow(this.context),
11893
12115
  workspace: (current, mutation) => success(mutation.revision, mutation.revision, current),
@@ -11925,7 +12147,7 @@ class WorkitCore {
11925
12147
  return failure("permission_denied", "worker report is outside the worker assignment");
11926
12148
  const changed = this.store.mutateTaskAndWorkspace({
11927
12149
  taskId: task.data.id,
11928
- expectedTaskRevision: input.expectedRevision,
12150
+ expectedRevision: input.expectedRevision,
11929
12151
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
11930
12152
  now: trustedNow(this.context),
11931
12153
  workspace: (current, mutation) => success(mutation.revision, mutation.revision, current),
@@ -11949,24 +12171,25 @@ class WorkitCore {
11949
12171
  return failure("invalid_transition", "closed task cannot cancel workers");
11950
12172
  if (entry.data.state === "unknown")
11951
12173
  return failure("recovery_required", "worker state requires recovery");
11952
- if (entry.data.state === "stopped")
11953
- return failure("invalid_transition", "stopped worker cannot be cancelled");
11954
- const settles = entry.data.report !== null || entry.data.state === "cancelling";
12174
+ if (entry.data.state === "stopped") {
12175
+ const stopped = task.data.workers.find((candidate) => candidate.id === input.workerId);
12176
+ return success(task.data.revision, workspace.data.revision, stopped);
12177
+ }
11955
12178
  const changed = this.store.mutateTaskAndWorkspace({
11956
12179
  taskId: task.data.id,
11957
- expectedTaskRevision: input.expectedRevision,
12180
+ expectedRevision: input.expectedRevision,
11958
12181
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
11959
12182
  now: trustedNow(this.context),
11960
- workspace: (current, mutation) => success(mutation.revision, mutation.revision, current),
12183
+ workspace: (current, mutation) => success(mutation.revision, mutation.revision, {
12184
+ ...current,
12185
+ writer: current.writer?.owner.workerId === input.workerId ? null : current.writer
12186
+ }),
11961
12187
  task: (current, mutation) => success(mutation.revision, null, {
11962
12188
  ...current,
11963
12189
  workers: current.workers.map((candidate) => candidate.id === input.workerId ? {
11964
12190
  ...candidate,
11965
12191
  recordedAt: mutation.now,
11966
- data: {
11967
- ...candidate.data,
11968
- state: settles ? "stopped" : "cancelling"
11969
- }
12192
+ data: { ...candidate.data, state: "stopped" }
11970
12193
  } : candidate)
11971
12194
  })
11972
12195
  });
@@ -12063,7 +12286,7 @@ class WorkitCore {
12063
12286
  return attested;
12064
12287
  const changed = this.store.mutateTaskAndWorkspace({
12065
12288
  taskId: task.data.id,
12066
- expectedTaskRevision: input.expectedRevision,
12289
+ expectedRevision: input.expectedRevision,
12067
12290
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
12068
12291
  now: trustedNow(this.context),
12069
12292
  workspace: (current, mutation) => success(mutation.revision, mutation.revision, current),
@@ -12229,6 +12452,12 @@ class WorkitCore {
12229
12452
  if (!sameSession2(helper.data.data.session, this.context))
12230
12453
  return failure("permission_denied", "worker session does not match the caller");
12231
12454
  }
12455
+ const gate = this.view(task.data);
12456
+ if (gate.ok) {
12457
+ const writeGates = (task.data.policy?.requirements ?? []).filter((requirement) => requirement.before === "write" && gate.data.requirements.some((evaluation) => evaluation.requirementId === requirement.id && (evaluation.status === "unsatisfied" || evaluation.status === "unavailable")));
12458
+ if (writeGates.length)
12459
+ return failure("requirements_unsatisfied", "writer ownership is gated by unsatisfied requirements; record their evidence or an approved limitation waiver first", { requirementIds: writeGates.map((requirement) => requirement.id) });
12460
+ }
12232
12461
  const owner = {
12233
12462
  taskId: task.data.id,
12234
12463
  workerId: helperId,
@@ -12240,7 +12469,7 @@ class WorkitCore {
12240
12469
  };
12241
12470
  const changed = this.store.mutateTaskAndWorkspace({
12242
12471
  taskId: task.data.id,
12243
- expectedTaskRevision: input.expectedRevision,
12472
+ expectedRevision: input.expectedRevision,
12244
12473
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
12245
12474
  now: trustedNow(this.context),
12246
12475
  workspace: (current, mutation) => success(mutation.revision, mutation.revision, {
@@ -12271,7 +12500,7 @@ class WorkitCore {
12271
12500
  }
12272
12501
  const changed = this.store.mutateTaskAndWorkspace({
12273
12502
  taskId: task.data.id,
12274
- expectedTaskRevision: input.expectedRevision,
12503
+ expectedRevision: input.expectedRevision,
12275
12504
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
12276
12505
  now: trustedNow(this.context),
12277
12506
  workspace: (currentWorkspace, mutation) => success(mutation.revision, mutation.revision, { ...currentWorkspace, writer: null }),
@@ -12520,7 +12749,15 @@ class WorkitCore {
12520
12749
  if (seen.has(observation.workerId))
12521
12750
  return failure("invalid_input", "worker observations must be unique");
12522
12751
  seen.add(observation.workerId);
12523
- if (observation.taskId !== view.task.id || observation.expectedRevision !== view.task.revision || observation.expectedWorkspaceRevision !== view.workspace.revision)
12752
+ const freshTask = this.store.readTask(view.task.id);
12753
+ const freshWorkspace = this.store.readWorkspace();
12754
+ if (!freshTask.ok)
12755
+ return freshTask;
12756
+ if (!freshWorkspace.ok)
12757
+ return freshWorkspace;
12758
+ if (!freshWorkspace.data)
12759
+ return failure("not_found", "workspace not found");
12760
+ if (observation.taskId !== view.task.id || observation.expectedRevision !== freshTask.data.revision || observation.expectedWorkspaceRevision !== freshWorkspace.data.revision)
12524
12761
  return failure("revision_conflict", "worker observation is stale");
12525
12762
  if (!view.task.workers.some((entry) => entry.id === observation.workerId))
12526
12763
  return failure("permission_denied", "worker observation is not assigned");
@@ -12606,19 +12843,26 @@ class WorkitCore {
12606
12843
  return failure("permission_denied", "imported resume requires native destination approval");
12607
12844
  resumeCandidate = current.data.candidate;
12608
12845
  }
12609
- const blocker = this.activeWorkerBlocker(task.data, workspace.data);
12846
+ const blocker = status === "paused" ? workspace.data.writer ? failure("recovery_required", "writer ownership must be released first") : null : this.activeWorkerBlocker(task.data, workspace.data);
12610
12847
  if (blocker)
12611
12848
  return blocker;
12849
+ let pauseCandidate = null;
12850
+ if (status === "paused") {
12851
+ const captured = captureCandidate(this.store.root, task.data.intent.data.scope, environment());
12852
+ if (!captured.ok)
12853
+ return captured;
12854
+ pauseCandidate = captured.data;
12855
+ }
12612
12856
  const changed = this.store.mutateTaskAndWorkspace({
12613
12857
  taskId: task.data.id,
12614
- expectedTaskRevision: input.expectedRevision,
12858
+ expectedRevision: input.expectedRevision,
12615
12859
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
12616
12860
  now: trustedNow(this.context),
12617
12861
  workspace: (workspace, context) => success(context.revision, context.revision, workspace),
12618
12862
  task: (current, context) => success(context.revision, null, {
12619
12863
  ...current,
12620
12864
  status,
12621
- candidates: resumeCandidate && !current.candidates.some((candidate) => candidate.id === resumeCandidate.id) ? [...current.candidates, resumeCandidate] : current.candidates,
12865
+ candidates: (resumeCandidate ?? pauseCandidate) && !current.candidates.some((candidate) => candidate.id === (resumeCandidate ?? pauseCandidate).id) ? [...current.candidates, resumeCandidate ?? pauseCandidate] : current.candidates,
12622
12866
  progress: current.progress,
12623
12867
  pauseReason: status === "paused" ? input.reason ?? null : null
12624
12868
  })
@@ -12656,12 +12900,13 @@ class WorkitCore {
12656
12900
  return workspace;
12657
12901
  if (!workspace.data)
12658
12902
  return failure("not_found", "workspace not found");
12659
- if (workspace.data.writer || task.data.workers.some((entry) => isUncertainWorker(entry.data.state)))
12660
- return failure("recovery_required", "scope revision requires worker ownership reconciliation");
12903
+ const revisionBlocker = this.activeWorkerBlocker(task.data, workspace.data);
12904
+ if (revisionBlocker)
12905
+ return revisionBlocker;
12661
12906
  this.fillRevisions(input, task.data, workspace.data);
12662
12907
  const changed = this.store.mutateTaskAndWorkspace({
12663
12908
  taskId: task.data.id,
12664
- expectedTaskRevision: input.expectedRevision,
12909
+ expectedRevision: input.expectedRevision,
12665
12910
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
12666
12911
  now: trustedNow(this.context),
12667
12912
  workspace: (workspace, context) => success(context.revision, context.revision, workspace),
@@ -12717,7 +12962,7 @@ class WorkitCore {
12717
12962
  return closure;
12718
12963
  const changed = this.store.mutateTaskAndWorkspace({
12719
12964
  taskId: task.data.id,
12720
- expectedTaskRevision: input.expectedRevision,
12965
+ expectedRevision: input.expectedRevision,
12721
12966
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
12722
12967
  now: trustedNow(this.context),
12723
12968
  workspace: (value, context) => success(context.revision, context.revision, value),
@@ -12842,6 +13087,8 @@ var provenance = (context, kind = context.provenanceKind ?? "host_observed") =>
12842
13087
  if (task.data.status === "paused" && (input.state === "running" || input.state === "cancelling"))
12843
13088
  return failure("invalid_transition", "paused task cannot run a worker");
12844
13089
  const notStarted = input.dispatch === true;
13090
+ if (notStarted && entry.data.state === "stopped" && input.session === null)
13091
+ return success(task.data.revision, workspace.data.revision, entry);
12845
13092
  if (notStarted && (input.state !== "stopped" || input.session !== null))
12846
13093
  return failure("invalid_input", "a never-dispatched worker stops with no session");
12847
13094
  if (notStarted && entry.data.session !== null)
@@ -12873,7 +13120,7 @@ var provenance = (context, kind = context.provenanceKind ?? "host_observed") =>
12873
13120
  return success(task.data.revision, workspace.data.revision, entry);
12874
13121
  const changed = input.store.mutateTaskAndWorkspace({
12875
13122
  taskId: task.data.id,
12876
- expectedTaskRevision: input.expectedRevision,
13123
+ expectedRevision: input.expectedRevision,
12877
13124
  expectedWorkspaceRevision: input.expectedWorkspaceRevision,
12878
13125
  now: input.now,
12879
13126
  workspace: (current, mutation) => success(mutation.revision, mutation.revision, {
@@ -12912,90 +13159,22 @@ var provenance = (context, kind = context.provenanceKind ?? "host_observed") =>
12912
13159
  workerId: null,
12913
13160
  receipts: []
12914
13161
  }), portableTask = (task) => {
12915
- const clone = structuredClone(task);
12916
- const portableProvenance = (value) => ({
12917
- ...value,
12918
- session: null,
12919
- receipts: []
12920
- });
12921
- const entries = [
12922
- clone.intent,
12923
- ...clone.assessments,
12924
- ...clone.evidence,
12925
- ...clone.decisions,
12926
- ...clone.findings,
12927
- ...clone.workers
12928
- ];
12929
- for (const entry of entries)
12930
- entry.provenance = portableProvenance(entry.provenance);
12931
- for (const worker of clone.workers)
12932
- worker.data.session = null;
12933
- clone.intent = {
12934
- ...clone.intent,
12935
- data: { ...clone.intent.data, authorityRefs: portableRefs(clone.intent.data.authorityRefs) }
12936
- };
12937
- clone.constraints = clone.constraints.flatMap((constraint) => {
12938
- const source = portableRef(constraint.source);
12939
- return source ? [
12940
- {
12941
- ...constraint,
12942
- source,
12943
- requires: constraint.requires.map((requirement) => ({
12944
- ...requirement,
12945
- refs: portableRefs(requirement.refs)
12946
- }))
12947
- }
12948
- ] : [];
12949
- });
12950
- clone.assessments = clone.assessments.map((entry) => ({
12951
- ...entry,
12952
- data: {
12953
- ...entry.data,
12954
- facts: entry.data.facts.map(portableFact),
12955
- signals: Object.fromEntries(Object.entries(entry.data.signals).map(([name, signal]) => [name, portableSignal(signal)])),
12956
- consequences: entry.data.consequences.map((consequence) => ({
12957
- ...consequence,
12958
- fact: portableFact(consequence.fact)
12959
- })),
12960
- verification: entry.data.verification.map((verification) => ({
12961
- ...verification,
12962
- availableChecks: portableRefs(verification.availableChecks)
12963
- }))
12964
- }
12965
- }));
12966
- clone.progress = {
12967
- ...clone.progress,
12968
- blockers: clone.progress.blockers.map((blocker) => ({
12969
- ...blocker,
12970
- refs: portableRefs(blocker.refs)
12971
- }))
13162
+ const stripped = rewriteRecordRefs(task, taskRecordSchema, portableRef);
13163
+ if (typeof stripped !== "object" || stripped === null || Array.isArray(stripped))
13164
+ throw new TypeError("portable task rewrite produced a non-record");
13165
+ const clone = structuredClone(stripped);
13166
+ const demote = (facts, signals, consequences) => {
13167
+ for (const fact of facts)
13168
+ Object.assign(fact, portableFact(fact));
13169
+ for (const name of Object.keys(signals)) {
13170
+ const signal = signals[name];
13171
+ Object.assign(signal, portableSignal(signal));
13172
+ }
13173
+ for (const consequence of consequences)
13174
+ Object.assign(consequence.fact, portableFact(consequence.fact));
12972
13175
  };
12973
- clone.evidence = clone.evidence.map((entry) => ({
12974
- ...entry,
12975
- data: {
12976
- ...entry.data,
12977
- refs: portableRefs(entry.data.refs),
12978
- reviewContext: portableRef(entry.data.reviewContext)
12979
- }
12980
- }));
12981
- clone.decisions = clone.decisions.map((entry) => ({
12982
- ...entry,
12983
- data: {
12984
- ...entry.data,
12985
- consumption: entry.data.consumption ? portableRef(entry.data.consumption.actionRef) ? {
12986
- ...entry.data.consumption,
12987
- actionRef: portableRef(entry.data.consumption.actionRef)
12988
- } : null : null,
12989
- binding: {
12990
- ...entry.data.binding,
12991
- contentRefs: portableRefs(entry.data.binding.contentRefs)
12992
- }
12993
- }
12994
- }));
12995
- clone.findings = clone.findings.map((entry) => ({
12996
- ...entry,
12997
- data: { ...entry.data, refs: portableRefs(entry.data.refs) }
12998
- }));
13176
+ for (const entry of clone.assessments)
13177
+ demote(entry.data.facts, entry.data.signals, entry.data.consequences);
12999
13178
  clone.candidates = [];
13000
13179
  return clone;
13001
13180
  }, importedTask = (source, bundle, destinationWorkspaceId, context, timestamp) => {
@@ -13019,15 +13198,13 @@ var provenance = (context, kind = context.provenanceKind ?? "host_observed") =>
13019
13198
  allocate(entry.id);
13020
13199
  const fresh = (id) => allocate(id);
13021
13200
  const provenance = importedProvenance(context);
13201
+ const remap = (ref) => mapRef(ref, ids);
13022
13202
  const intent = {
13023
13203
  ...source.intent,
13024
13204
  id: fresh(source.intent.id),
13025
13205
  recordedAt: timestamp,
13026
13206
  provenance,
13027
- data: {
13028
- ...source.intent.data,
13029
- authorityRefs: source.intent.data.authorityRefs.map((ref) => mapRef(ref, ids))
13030
- }
13207
+ data: rewriteRecordRefs(source.intent.data, intentSchema, remap)
13031
13208
  };
13032
13209
  const assessments = source.assessments.map((entry) => {
13033
13210
  const data = entry.data;
@@ -13036,28 +13213,7 @@ var provenance = (context, kind = context.provenanceKind ?? "host_observed") =>
13036
13213
  id: fresh(entry.id),
13037
13214
  recordedAt: timestamp,
13038
13215
  provenance,
13039
- data: {
13040
- ...data,
13041
- facts: data.facts.map((fact) => ({
13042
- ...fact,
13043
- refs: fact.refs.map((ref) => mapRef(ref, ids))
13044
- })),
13045
- signals: Object.fromEntries(Object.entries(data.signals).map(([name, signal]) => [
13046
- name,
13047
- { ...signal, refs: signal.refs.map((ref) => mapRef(ref, ids)) }
13048
- ])),
13049
- consequences: data.consequences.map((consequence) => ({
13050
- ...consequence,
13051
- fact: {
13052
- ...consequence.fact,
13053
- refs: consequence.fact.refs.map((ref) => mapRef(ref, ids))
13054
- }
13055
- })),
13056
- verification: data.verification.map((verification) => ({
13057
- ...verification,
13058
- availableChecks: verification.availableChecks.map((ref) => mapRef(ref, ids))
13059
- }))
13060
- }
13216
+ data: rewriteRecordRefs(data, assessmentSchema, remap)
13061
13217
  };
13062
13218
  });
13063
13219
  const evidence = source.evidence.map((entry) => ({
@@ -13065,11 +13221,7 @@ var provenance = (context, kind = context.provenanceKind ?? "host_observed") =>
13065
13221
  id: fresh(entry.id),
13066
13222
  recordedAt: timestamp,
13067
13223
  provenance,
13068
- data: {
13069
- ...entry.data,
13070
- refs: entry.data.refs.map((ref) => mapRef(ref, ids)),
13071
- reviewContext: entry.data.reviewContext ? mapRef(entry.data.reviewContext, ids) : null
13072
- }
13224
+ data: rewriteRecordRefs(entry.data, evidenceSchema, remap)
13073
13225
  }));
13074
13226
  const decisions = source.decisions.map((entry) => ({
13075
13227
  ...entry,
@@ -13077,21 +13229,23 @@ var provenance = (context, kind = context.provenanceKind ?? "host_observed") =>
13077
13229
  recordedAt: timestamp,
13078
13230
  provenance
13079
13231
  }));
13080
- const findings = source.findings.map((entry) => ({
13081
- ...entry,
13082
- id: fresh(entry.id),
13083
- recordedAt: timestamp,
13084
- provenance,
13085
- data: {
13086
- ...entry.data,
13087
- refs: entry.data.refs.map((ref) => mapRef(ref, ids)),
13088
- resolution: entry.data.resolution ? {
13089
- ...entry.data.resolution,
13090
- evidenceIds: entry.data.resolution.evidenceIds.map((id) => ids.get(id) ?? id),
13091
- decisionIds: entry.data.resolution.decisionIds.map((id) => ids.get(id) ?? id)
13092
- } : null
13093
- }
13094
- }));
13232
+ const findings = source.findings.map((entry) => {
13233
+ const data = rewriteRecordRefs(entry.data, findingSchema, remap);
13234
+ return {
13235
+ ...entry,
13236
+ id: fresh(entry.id),
13237
+ recordedAt: timestamp,
13238
+ provenance,
13239
+ data: {
13240
+ ...data,
13241
+ resolution: data.resolution ? {
13242
+ ...data.resolution,
13243
+ evidenceIds: data.resolution.evidenceIds.map((id) => ids.get(id) ?? id),
13244
+ decisionIds: data.resolution.decisionIds.map((id) => ids.get(id) ?? id)
13245
+ } : null
13246
+ }
13247
+ };
13248
+ });
13095
13249
  const workers = source.workers.map((entry) => ({
13096
13250
  ...entry,
13097
13251
  id: fresh(entry.id),
@@ -13134,19 +13288,21 @@ var provenance = (context, kind = context.provenanceKind ?? "host_observed") =>
13134
13288
  closure: null,
13135
13289
  assessments,
13136
13290
  evidence,
13137
- decisions: decisions.map((entry) => ({
13138
- ...entry,
13139
- data: {
13140
- ...entry.data,
13141
- binding: {
13142
- ...entry.data.binding,
13143
- taskId: "",
13144
- workspaceId: destinationWorkspaceId,
13145
- contentRefs: entry.data.binding.contentRefs.map((ref) => mapRef(ref, ids))
13146
- },
13147
- consumption: null
13148
- }
13149
- })),
13291
+ decisions: decisions.map((entry) => {
13292
+ const data = rewriteRecordRefs(entry.data, decisionSchema, remap);
13293
+ return {
13294
+ ...entry,
13295
+ data: {
13296
+ ...data,
13297
+ binding: {
13298
+ ...data.binding,
13299
+ taskId: "",
13300
+ workspaceId: destinationWorkspaceId
13301
+ },
13302
+ consumption: null
13303
+ }
13304
+ };
13305
+ }),
13150
13306
  ...actionProgress ? { actionProgress } : {},
13151
13307
  findings,
13152
13308
  workers,
@@ -13188,6 +13344,9 @@ var init_core3 = __esm(() => {
13188
13344
  init_task_context();
13189
13345
  init_methods();
13190
13346
  init_route_intent();
13347
+ init_branch();
13348
+ init_runtime_identity();
13349
+ init_authority();
13191
13350
  init_authority();
13192
13351
  init_external_action();
13193
13352
  init_external_action();
@@ -13252,8 +13411,8 @@ var hostRef = (handle) => ({ kind: "host", host: "cursor", handle }), cursorCapa
13252
13411
  refs: [hostRef("sessionStart"), hostRef("preCompact")]
13253
13412
  }
13254
13413
  ];
13255
- }, isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value), eventNames, nonEmpty2 = (value) => typeof value === "string" && value.trim() !== "", parseCursorHookInput = (value) => {
13256
- if (!isRecord(value) || !eventNames.has(value.hook_event_name))
13414
+ }, isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), eventNames, nonEmpty2 = (value) => typeof value === "string" && value.trim() !== "", parseCursorHookInput = (value) => {
13415
+ if (!isRecord2(value) || !eventNames.has(value.hook_event_name))
13257
13416
  return { ok: false, error: "hook_event_name is required" };
13258
13417
  const roots = value.workspace_roots;
13259
13418
  if (!Array.isArray(roots) || roots.length !== 1 || !roots.every(nonEmpty2))
@@ -13391,7 +13550,7 @@ var hostRef = (handle) => ({ kind: "host", host: "cursor", handle }), cursorCapa
13391
13550
  }, handleSubagentStop = () => ({}), handleCursorHook = (raw) => {
13392
13551
  const parsed = parseCursorHookInput(raw);
13393
13552
  if (!parsed.ok) {
13394
- return isRecord(raw) && raw.hook_event_name === "sessionStart" ? {} : deny(parsed.error);
13553
+ return isRecord2(raw) && raw.hook_event_name === "sessionStart" ? {} : deny(parsed.error);
13395
13554
  }
13396
13555
  const input = parsed.data;
13397
13556
  const root = realpathSync5(input.workspace_roots[0]);
@@ -13435,7 +13594,7 @@ ${invariantBootstrap()}${compact}
13435
13594
  const output = handleCursorHook(input);
13436
13595
  process.stdout.write(`${JSON.stringify(output)}
13437
13596
  `);
13438
- const event = isRecord(input) ? input.hook_event_name : undefined;
13597
+ const event = isRecord2(input) ? input.hook_event_name : undefined;
13439
13598
  if (output.permission === "deny" && ["preToolUse", "beforeShellExecution", "subagentStart"].includes(String(event)))
13440
13599
  process.exitCode = 2;
13441
13600
  } catch {