@brainervirus/workit-codex 1.0.10 → 1.0.11

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workit",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "Adaptive engineering workflow rails for Codex",
5
5
  "author": {
6
6
  "name": "BrainerVirus"
@@ -14420,10 +14420,11 @@ var decisionSchema = object({
14420
14420
  presented: text,
14421
14421
  approvedContent: text,
14422
14422
  displayed: text.optional(),
14423
- contentRefs: array(refSchema)
14423
+ contentRefs: array(refSchema),
14424
+ statedChoice: object({ ref: text, text }).strict().optional()
14424
14425
  }).strict(),
14425
14426
  digest,
14426
- response: _enum(["approved", "rejected"]),
14427
+ response: _enum(["approved", "rejected", "stated"]),
14427
14428
  requirementIds: array(digest),
14428
14429
  revoked: object({ at: utc, reason: text }).strict().nullable(),
14429
14430
  consumption: object({
@@ -17275,7 +17276,7 @@ function evaluateEvidence(task, candidate) {
17275
17276
  }
17276
17277
  var scopeCovers2 = scopeCovers;
17277
17278
  var 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")));
17278
- var 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 }));
17279
+ var 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 }));
17279
17280
  var evidenceMatchesRequirement = (kind, evidenceKind, dimension) => {
17280
17281
  if (kind !== "passed")
17281
17282
  return false;
@@ -17351,7 +17352,7 @@ function evaluateRequirements(task, workspace, capabilities, candidate, checkout
17351
17352
  status: "satisfied",
17352
17353
  evidenceIds: [],
17353
17354
  decisionIds: decisions.map((decision) => decision.id),
17354
- reason: "an applicable approved decision satisfies the requirement"
17355
+ reason: "an applicable approved or stated decision satisfies the requirement"
17355
17356
  };
17356
17357
  const limitations = requirement.acceptanceAllowed ? applicableDecision2(task, workspace, requirement, checkoutRoot) : [];
17357
17358
  if (limitations.length)
@@ -18717,7 +18718,12 @@ class WorkitCore {
18717
18718
  const input = parsed.data;
18718
18719
  if (nativeRequired && input.action !== "record")
18719
18720
  return failure("permission_denied", "native observation is only valid for recording decisions");
18720
- if (nativeRequired && nativeObservation === undefined)
18721
+ const stated = input.action === "record" && input.response === "stated";
18722
+ if (stated && input.purpose === "action")
18723
+ return failure("permission_denied", "stated choices cannot authorize mutating actions");
18724
+ if (stated && !input.binding?.statedChoice)
18725
+ return failure("invalid_input", "stated choices require binding.statedChoice");
18726
+ if (nativeRequired && nativeObservation === undefined && !stated)
18721
18727
  return failure("permission_denied", "native decision observation is required");
18722
18728
  const task = this.store.readTask(input.taskId);
18723
18729
  if (!task.ok)
@@ -18750,7 +18756,7 @@ class WorkitCore {
18750
18756
  consumption: null
18751
18757
  };
18752
18758
  const data = { ...base, digest: decisionDigest(base) };
18753
- const native = nativeRequired ? verifyNativeDecision(this.context.nativeAuthority, {
18759
+ const native = nativeRequired && !stated ? verifyNativeDecision(this.context.nativeAuthority, {
18754
18760
  observation: nativeObservation,
18755
18761
  expected: {
18756
18762
  taskId: task.data.id,
@@ -7574,10 +7574,11 @@ var decisionSchema = object({
7574
7574
  presented: text,
7575
7575
  approvedContent: text,
7576
7576
  displayed: text.optional(),
7577
- contentRefs: array(refSchema)
7577
+ contentRefs: array(refSchema),
7578
+ statedChoice: object({ ref: text, text }).strict().optional()
7578
7579
  }).strict(),
7579
7580
  digest,
7580
- response: _enum(["approved", "rejected"]),
7581
+ response: _enum(["approved", "rejected", "stated"]),
7581
7582
  requirementIds: array(digest),
7582
7583
  revoked: object({ at: utc, reason: text }).strict().nullable(),
7583
7584
  consumption: object({
@@ -10368,7 +10369,7 @@ function evaluateEvidence(task, candidate) {
10368
10369
  }
10369
10370
  var scopeCovers2 = scopeCovers;
10370
10371
  var 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")));
10371
- var 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 }));
10372
+ var 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 }));
10372
10373
  var evidenceMatchesRequirement = (kind, evidenceKind, dimension) => {
10373
10374
  if (kind !== "passed")
10374
10375
  return false;
@@ -10444,7 +10445,7 @@ function evaluateRequirements(task, workspace, capabilities, candidate, checkout
10444
10445
  status: "satisfied",
10445
10446
  evidenceIds: [],
10446
10447
  decisionIds: decisions.map((decision) => decision.id),
10447
- reason: "an applicable approved decision satisfies the requirement"
10448
+ reason: "an applicable approved or stated decision satisfies the requirement"
10448
10449
  };
10449
10450
  const limitations = requirement.acceptanceAllowed ? applicableDecision2(task, workspace, requirement, checkoutRoot) : [];
10450
10451
  if (limitations.length)
@@ -10777,6 +10778,23 @@ function shellRouteIntent(command) {
10777
10778
  }
10778
10779
  return null;
10779
10780
  }
10781
+ function hasLiveWorkitTask(dir) {
10782
+ try {
10783
+ if (typeof dir !== "string" || dir === "")
10784
+ return false;
10785
+ const listed = new TaskStore(dir).listTasks();
10786
+ if (!listed.ok)
10787
+ return false;
10788
+ return listed.data.some((task) => task.status === "active" || task.status === "paused");
10789
+ } catch {
10790
+ return false;
10791
+ }
10792
+ }
10793
+ function shouldDenyShellRoute(dir, command) {
10794
+ if (!hasLiveWorkitTask(dir))
10795
+ return null;
10796
+ return shellRouteIntent(command);
10797
+ }
10780
10798
  // packages/workit-core/src/core/external-action.ts
10781
10799
  var externalActionSchema = discriminatedUnion("operation", [
10782
10800
  object({
@@ -12022,7 +12040,12 @@ class WorkitCore {
12022
12040
  const input = parsed.data;
12023
12041
  if (nativeRequired && input.action !== "record")
12024
12042
  return failure("permission_denied", "native observation is only valid for recording decisions");
12025
- if (nativeRequired && nativeObservation === undefined)
12043
+ const stated = input.action === "record" && input.response === "stated";
12044
+ if (stated && input.purpose === "action")
12045
+ return failure("permission_denied", "stated choices cannot authorize mutating actions");
12046
+ if (stated && !input.binding?.statedChoice)
12047
+ return failure("invalid_input", "stated choices require binding.statedChoice");
12048
+ if (nativeRequired && nativeObservation === undefined && !stated)
12026
12049
  return failure("permission_denied", "native decision observation is required");
12027
12050
  const task = this.store.readTask(input.taskId);
12028
12051
  if (!task.ok)
@@ -12055,7 +12078,7 @@ class WorkitCore {
12055
12078
  consumption: null
12056
12079
  };
12057
12080
  const data = { ...base, digest: decisionDigest(base) };
12058
- const native = nativeRequired ? verifyNativeDecision(this.context.nativeAuthority, {
12081
+ const native = nativeRequired && !stated ? verifyNativeDecision(this.context.nativeAuthority, {
12059
12082
  observation: nativeObservation,
12060
12083
  expected: {
12061
12084
  taskId: task.data.id,
@@ -13386,7 +13409,7 @@ var handleCodexHook = (raw) => {
13386
13409
  if (input.hook_event_name === "PreToolUse") {
13387
13410
  if (["bash", "unified-exec"].includes(String(input.tool_name).toLowerCase())) {
13388
13411
  const command = record2(input.tool_input) ? input.tool_input.command : undefined;
13389
- const route = typeof command === "string" ? shellRouteIntent(command) : null;
13412
+ const route = typeof command === "string" ? shouldDenyShellRoute(input.cwd, command) : null;
13390
13413
  if (route)
13391
13414
  return denied("PreToolUse", `direct branch or PR creation bypasses the Workit route; ${route.guidance}`);
13392
13415
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-codex",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "private": false,
5
5
  "description": "Workit Codex CLI/desktop plugin — shared MCP transport, hooks, and fourteen method skills",
6
6
  "keywords": [
@@ -38,8 +38,8 @@
38
38
  "build": "bun scripts/build.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@brainervirus/workit-core": "^1.0.10",
42
- "@brainervirus/workit-mcp": "^1.0.10"
41
+ "@brainervirus/workit-core": "^1.0.11",
42
+ "@brainervirus/workit-mcp": "^1.0.11"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=24"