@brainervirus/workit-cursor 8.11.0 → 8.12.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.
@@ -2,7 +2,7 @@
2
2
  "name": "workit",
3
3
  "displayName": "Workit",
4
4
  "description": "Adaptive Workit workflow with shared MCP tools and native Cursor hooks",
5
- "version": "8.11.0",
5
+ "version": "8.12.0",
6
6
  "author": {
7
7
  "name": "Cristhofer Pincetti"
8
8
  },
@@ -9120,8 +9120,8 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
9120
9120
  profiles: record(nonBlank, profileSchema).optional()
9121
9121
  }).passthrough();
9122
9122
  return entrySchema;
9123
- }, resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd, "vcs"), runtimeWorkspaceIndexSchema, matchRuntimeWorkspace = (cwd) => {
9124
- const file = path3.join(configDir(), "workspaces.json");
9123
+ }, resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd, "vcs"), runtimeWorkspaceIndexSchema, matchRuntimeWorkspace = (cwd, dir = configDir()) => {
9124
+ const file = path3.join(dir, "workspaces.json");
9125
9125
  let raw;
9126
9126
  try {
9127
9127
  raw = readFileSync2(file, "utf8");
@@ -9150,10 +9150,27 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
9150
9150
  const matches = matchingEntries(cwd, entries ?? []);
9151
9151
  const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
9152
9152
  const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
9153
- return selected ? { file, selected } : null;
9153
+ return selected ? { file, selected, matches } : null;
9154
9154
  }, resolveRuntimeReleaseTracks = (cwd) => {
9155
9155
  const matched = matchRuntimeWorkspace(cwd);
9156
9156
  return matched ? { workspace: matched.selected.name, releaseTracks: matched.selected.releaseTracks } : null;
9157
+ }, workspaceTrailers = (cwd, dir) => {
9158
+ let matched;
9159
+ try {
9160
+ matched = matchRuntimeWorkspace(cwd, dir);
9161
+ } catch {
9162
+ return { enabled: true, workspace: null, from: null };
9163
+ }
9164
+ if (!matched)
9165
+ return { enabled: true, workspace: null, from: null };
9166
+ const { selected, matches } = matched;
9167
+ const enclosing = matches.filter((entry) => entry !== selected).toSorted((a, b) => globSpecificity(b.glob) - globSpecificity(a.glob));
9168
+ const source = [selected, ...enclosing].find((entry) => typeof entry.trailers === "boolean");
9169
+ return {
9170
+ enabled: source?.trailers !== false,
9171
+ workspace: selected.name,
9172
+ from: source?.name ?? null
9173
+ };
9157
9174
  }, resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
9158
9175
  const matched = matchRuntimeWorkspace(cwd);
9159
9176
  if (!matched)
@@ -9264,6 +9281,7 @@ var init_workspaces = __esm(() => {
9264
9281
  autoApprove: union([boolean2(), array(nonBlank)]).optional(),
9265
9282
  defaultEndpoint: unknown().optional(),
9266
9283
  verification: _enum(["self", "independent"]).optional(),
9284
+ trailers: boolean2().optional(),
9267
9285
  autonomy: object(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
9268
9286
  kind,
9269
9287
  union([boolean2(), literal("verified")]).optional()
@@ -14783,7 +14801,7 @@ function loadCheckConfig(cwd) {
14783
14801
  gates[gate] = names;
14784
14802
  }
14785
14803
  }
14786
- return { source: CHECKS_FILE, root, checks, gates, error: null };
14804
+ return { source: CHECKS_FILE, root, checks, gates, error: null, resources: parsed.resources };
14787
14805
  }
14788
14806
  function matchesNamedCheck(config, name, argv, cwd) {
14789
14807
  if (config.error || name === null || cwd !== ".")
@@ -15550,9 +15568,9 @@ Autonomy contract:
15550
15568
  ship), go to the effective endpoint in \`workit grant show\`: \`pr\` opens
15551
15569
  the PR; \`green\` babysits it without asking (workit-ship) to merge-ready,
15552
15570
  never merging; \`merged\` also lands it with \`workit pr merge\`.
15553
- Merge and release need a workspace grant, which only the user raises from
15554
- their own terminal (a blocked verb names how); never edit workspaces.json or
15555
- route around a grant_required.
15571
+ Merge and release need a workspace grant only the user raises from their
15572
+ own terminal (a blocked verb names how); never edit workspaces.json or route
15573
+ around a grant_required.
15556
15574
  - Ask only for a product or preference choice, or for authority you lack, with
15557
15575
  your recommended answer. Facts are yours: read, run or prototype.
15558
15576
  - Label claims measured (run and seen this session), inferred, or guess.
@@ -15561,17 +15579,19 @@ Autonomy contract:
15561
15579
  - Author is not verifier: your own verdict is \`--self\`, shown as
15562
15580
  self-reviewed, never verified. High risk, \`verification: independent\` and
15563
15581
  merge need a verifier with its own host-derived session (a subagent's
15564
- \`<lead>:<child>\`, set by the host); never hand-mint one such as \`<lead>-v1\`.
15582
+ \`<lead>:<child>\`); never hand-mint one (\`<lead>-v1\`).
15565
15583
  - A local-commit endpoint does not imply PR readiness, and a local commit alone
15566
15584
  is not evidence of a requested remote push. Before reporting delivery,
15567
15585
  reconcile every requested item and observe it (\`workit verify-delivery\`).
15568
15586
 
15569
15587
  CLI first: if a step has one right answer, use the \`workit\` verb instead of
15570
15588
  hand-running git, gh or glab (\`workit git|pr|ci|check\`; \`workit help\` lists
15571
- the rest; without \`workit\` on PATH, \`npx -y @brainervirus/workit-cli\`).
15589
+ the rest; lacking \`workit\`, \`npx -y @brainervirus/workit-cli\`).
15590
+ Add Co-Authored-By via \`workit git commit --trailer "K: v" -- <paths>\`, never
15591
+ an amend.
15572
15592
  The task families (task, policy, evidence, finding, decision, worker, state)
15573
15593
  are optional continuity for tracked work; each branch has one implicit task,
15574
- created by the first recording, and a solo edit needs no task. A decision
15594
+ and a solo edit needs no task. A decision
15575
15595
  records a user choice; it never authorizes an effect. Judge work once with
15576
15596
  \`workit policy assess --judge risk= behavior= product-choice= plan=\`.
15577
15597
  Across repositories, bind each item to its checkout, branch and endpoint,
@@ -19362,16 +19382,16 @@ var usable2 = (value) => value === "native" || value === "partial", NONE5, resen
19362
19382
  const prefix = descriptor.subagents.agentPrefix;
19363
19383
  const name = agentType.startsWith(prefix) ? agentType.slice(prefix.length) : "";
19364
19384
  return Object.hasOwn(ROLES, name) ? ROLES[name] : null;
19365
- }, subagentSession = (session, agentId) => [session, agentId].filter((part) => Boolean(part)).join(":").replace(/[^A-Za-z0-9_.:@/+-]/g, "-").slice(0, 128), CLAUDE_WORKTREE, ISOLATED_GIT = 'Run git as plain, separate commands inside your worktree (`git switch -c <branch> <base>`, `git commit --trailer "Workit-Session=<your session>"`, `git push`; `workit doctor --fix` can install a commit-msg hook that adds the trailer), never `workit git …`: Claude Code\'s worktree isolation refuses a command that wraps git and cannot be turned off (https://code.claude.com/docs/en/worktrees#how-claude-code-enforces-isolation). Never dodge that check by renaming or re-wrapping git. Use workit for the non-git verbs (`workit check`, `workit ledger`, `workit pr`).', subagentStartText = (input, descriptor, event) => {
19385
+ }, subagentSession = (session, agentId) => [session, agentId].filter((part) => Boolean(part)).join(":").replace(/[^A-Za-z0-9_.:@/+-]/g, "-").slice(0, 128), CLAUDE_WORKTREE, isolatedGit = (cwd) => `Run git as plain, separate commands inside your worktree (\`git switch -c <branch> <base>\`, ${workspaceTrailers(cwd).enabled ? '`git commit --trailer "Workit-Session=<your session>"`, `git push`; `workit doctor --fix` can install a prepare-commit-msg hook that adds the trailer' : "`git commit` (this workspace sets trailers: false: add no Workit-Session trailer), `git push`"}; add Co-Authored-By with \`git commit --trailer\` in the same commit, never by amending), never \`workit git …\`: Claude Code's worktree isolation refuses a command that wraps git and cannot be turned off (https://code.claude.com/docs/en/worktrees#how-claude-code-enforces-isolation). Never dodge that check by renaming or re-wrapping git. Use workit for the non-git verbs (\`workit check\`, \`workit ledger\`, \`workit pr\`).`, subagentStartText = (input, descriptor, event) => {
19366
19386
  const session = input.session.id ?? null;
19367
19387
  const role = workitRole(descriptor, event.agentType);
19368
19388
  const who = `${descriptor.label} subagent ${event.agentId} (${event.agentType})`;
19369
19389
  const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer" || CLAUDE_WORKTREE.test(input.cwd));
19370
19390
  const guide = role === "implementer" ? branchGuidance(input.cwd) : null;
19371
19391
  if (role === "implementer" && isolated)
19372
- return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${ISOLATED_GIT} Plain git is expected here, and the branch name is still policy-checked: a raw \`git switch -c\`, \`git checkout -b\`, \`git branch\` or \`git worktree add -b\` onto a protected or non-compliant name is denied, so use a policy-compliant branch.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
19392
+ return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${isolatedGit(input.cwd)} Plain git is expected here, and the branch name is still policy-checked: a raw \`git switch -c\`, \`git checkout -b\`, \`git branch\` or \`git worktree add -b\` onto a protected or non-compliant name is denied, so use a policy-compliant branch.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
19373
19393
  if (isolated)
19374
- return `${ISOLATED_GIT}
19394
+ return `${isolatedGit(input.cwd)}
19375
19395
  ${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
19376
19396
  if (role === "implementer")
19377
19397
  return `Workit observed ${who} as an implementer: it edits and commits only in its own git worktree (the lead makes one with \`workit fanout worktree create <slice>\`), never in the lead's checkout, within its brief's scope. Before the first commit, switch to a policy-compliant branch with \`workit git branch <branch> --base <base>\` (or \`--kind <kind> --slug <slug>\`, which picks the base); branch policy hooks still deny protected or non-compliant branches, raw git included.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
@@ -19413,6 +19433,7 @@ ${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
19413
19433
  var init_handle = __esm(() => {
19414
19434
  init_context();
19415
19435
  init_branch();
19436
+ init_workspaces();
19416
19437
  init_host_session();
19417
19438
  init_policy();
19418
19439
  init_raw_git();
@@ -21230,7 +21230,7 @@ function loadCheckConfig(cwd) {
21230
21230
  gates[gate] = names;
21231
21231
  }
21232
21232
  }
21233
- return { source: CHECKS_FILE, root, checks, gates, error: null };
21233
+ return { source: CHECKS_FILE, root, checks, gates, error: null, resources: parsed.resources };
21234
21234
  }
21235
21235
  var sameArgv = (left, right) => left.length === right.length && left.every((item, index) => item === right[index]);
21236
21236
  function matchesNamedCheck(config, name, argv, cwd) {
@@ -21818,6 +21818,7 @@ var workspaceConfigSchema = object2({
21818
21818
  autoApprove: union([boolean2(), array(nonBlank)]).optional(),
21819
21819
  defaultEndpoint: unknown().optional(),
21820
21820
  verification: _enum(["self", "independent"]).optional(),
21821
+ trailers: boolean2().optional(),
21821
21822
  autonomy: object2(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
21822
21823
  kind,
21823
21824
  union([boolean2(), literal("verified")]).optional()
@@ -22099,8 +22100,8 @@ var resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd,
22099
22100
  var runtimeWorkspaceIndexSchema = object2({
22100
22101
  workspaces: array(object2({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
22101
22102
  }).passthrough();
22102
- var matchRuntimeWorkspace = (cwd) => {
22103
- const file = path10.join(configDir(), "workspaces.json");
22103
+ var matchRuntimeWorkspace = (cwd, dir = configDir()) => {
22104
+ const file = path10.join(dir, "workspaces.json");
22104
22105
  let raw;
22105
22106
  try {
22106
22107
  raw = readFileSync3(file, "utf8");
@@ -22129,7 +22130,7 @@ var matchRuntimeWorkspace = (cwd) => {
22129
22130
  const matches = matchingEntries(cwd, entries ?? []);
22130
22131
  const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
22131
22132
  const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
22132
- return selected ? { file, selected } : null;
22133
+ return selected ? { file, selected, matches } : null;
22133
22134
  };
22134
22135
  var resolveRuntimeReleaseTracks = (cwd) => {
22135
22136
  const matched = matchRuntimeWorkspace(cwd);
@@ -8921,6 +8921,7 @@ var workspaceConfigSchema = object({
8921
8921
  autoApprove: union([boolean2(), array(nonBlank)]).optional(),
8922
8922
  defaultEndpoint: unknown().optional(),
8923
8923
  verification: _enum(["self", "independent"]).optional(),
8924
+ trailers: boolean2().optional(),
8924
8925
  autonomy: object(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
8925
8926
  kind,
8926
8927
  union([boolean2(), literal("verified")]).optional()
@@ -9202,8 +9203,8 @@ var resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd,
9202
9203
  var runtimeWorkspaceIndexSchema = object({
9203
9204
  workspaces: array(object({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
9204
9205
  }).passthrough();
9205
- var matchRuntimeWorkspace = (cwd) => {
9206
- const file = path3.join(configDir(), "workspaces.json");
9206
+ var matchRuntimeWorkspace = (cwd, dir = configDir()) => {
9207
+ const file = path3.join(dir, "workspaces.json");
9207
9208
  let raw;
9208
9209
  try {
9209
9210
  raw = readFileSync2(file, "utf8");
@@ -9232,12 +9233,30 @@ var matchRuntimeWorkspace = (cwd) => {
9232
9233
  const matches = matchingEntries(cwd, entries ?? []);
9233
9234
  const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
9234
9235
  const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
9235
- return selected ? { file, selected } : null;
9236
+ return selected ? { file, selected, matches } : null;
9236
9237
  };
9237
9238
  var resolveRuntimeReleaseTracks = (cwd) => {
9238
9239
  const matched = matchRuntimeWorkspace(cwd);
9239
9240
  return matched ? { workspace: matched.selected.name, releaseTracks: matched.selected.releaseTracks } : null;
9240
9241
  };
9242
+ var workspaceTrailers = (cwd, dir) => {
9243
+ let matched;
9244
+ try {
9245
+ matched = matchRuntimeWorkspace(cwd, dir);
9246
+ } catch {
9247
+ return { enabled: true, workspace: null, from: null };
9248
+ }
9249
+ if (!matched)
9250
+ return { enabled: true, workspace: null, from: null };
9251
+ const { selected, matches } = matched;
9252
+ const enclosing = matches.filter((entry) => entry !== selected).toSorted((a, b) => globSpecificity(b.glob) - globSpecificity(a.glob));
9253
+ const source = [selected, ...enclosing].find((entry) => typeof entry.trailers === "boolean");
9254
+ return {
9255
+ enabled: source?.trailers !== false,
9256
+ workspace: selected.name,
9257
+ from: source?.name ?? null
9258
+ };
9259
+ };
9241
9260
  var resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
9242
9261
  const matched = matchRuntimeWorkspace(cwd);
9243
9262
  if (!matched)
@@ -14838,7 +14857,7 @@ function loadCheckConfig(cwd) {
14838
14857
  gates[gate] = names;
14839
14858
  }
14840
14859
  }
14841
- return { source: CHECKS_FILE, root, checks, gates, error: null };
14860
+ return { source: CHECKS_FILE, root, checks, gates, error: null, resources: parsed.resources };
14842
14861
  }
14843
14862
  var sameArgv = (left, right) => left.length === right.length && left.every((item, index) => item === right[index]);
14844
14863
  function matchesNamedCheck(config, name, argv, cwd) {
@@ -15605,9 +15624,9 @@ Autonomy contract:
15605
15624
  ship), go to the effective endpoint in \`workit grant show\`: \`pr\` opens
15606
15625
  the PR; \`green\` babysits it without asking (workit-ship) to merge-ready,
15607
15626
  never merging; \`merged\` also lands it with \`workit pr merge\`.
15608
- Merge and release need a workspace grant, which only the user raises from
15609
- their own terminal (a blocked verb names how); never edit workspaces.json or
15610
- route around a grant_required.
15627
+ Merge and release need a workspace grant only the user raises from their
15628
+ own terminal (a blocked verb names how); never edit workspaces.json or route
15629
+ around a grant_required.
15611
15630
  - Ask only for a product or preference choice, or for authority you lack, with
15612
15631
  your recommended answer. Facts are yours: read, run or prototype.
15613
15632
  - Label claims measured (run and seen this session), inferred, or guess.
@@ -15616,17 +15635,19 @@ Autonomy contract:
15616
15635
  - Author is not verifier: your own verdict is \`--self\`, shown as
15617
15636
  self-reviewed, never verified. High risk, \`verification: independent\` and
15618
15637
  merge need a verifier with its own host-derived session (a subagent's
15619
- \`<lead>:<child>\`, set by the host); never hand-mint one such as \`<lead>-v1\`.
15638
+ \`<lead>:<child>\`); never hand-mint one (\`<lead>-v1\`).
15620
15639
  - A local-commit endpoint does not imply PR readiness, and a local commit alone
15621
15640
  is not evidence of a requested remote push. Before reporting delivery,
15622
15641
  reconcile every requested item and observe it (\`workit verify-delivery\`).
15623
15642
 
15624
15643
  CLI first: if a step has one right answer, use the \`workit\` verb instead of
15625
15644
  hand-running git, gh or glab (\`workit git|pr|ci|check\`; \`workit help\` lists
15626
- the rest; without \`workit\` on PATH, \`npx -y @brainervirus/workit-cli\`).
15645
+ the rest; lacking \`workit\`, \`npx -y @brainervirus/workit-cli\`).
15646
+ Add Co-Authored-By via \`workit git commit --trailer "K: v" -- <paths>\`, never
15647
+ an amend.
15627
15648
  The task families (task, policy, evidence, finding, decision, worker, state)
15628
15649
  are optional continuity for tracked work; each branch has one implicit task,
15629
- created by the first recording, and a solo edit needs no task. A decision
15650
+ and a solo edit needs no task. A decision
15630
15651
  records a user choice; it never authorizes an effect. Judge work once with
15631
15652
  \`workit policy assess --judge risk= behavior= product-choice= plan=\`.
15632
15653
  Across repositories, bind each item to its checkout, branch and endpoint,
@@ -19402,7 +19423,7 @@ var workitRole = (descriptor, agentType) => {
19402
19423
  };
19403
19424
  var subagentSession = (session, agentId) => [session, agentId].filter((part) => Boolean(part)).join(":").replace(/[^A-Za-z0-9_.:@/+-]/g, "-").slice(0, 128);
19404
19425
  var CLAUDE_WORKTREE = /[\\/]\.claude[\\/]worktrees[\\/]/;
19405
- var ISOLATED_GIT = 'Run git as plain, separate commands inside your worktree (`git switch -c <branch> <base>`, `git commit --trailer "Workit-Session=<your session>"`, `git push`; `workit doctor --fix` can install a commit-msg hook that adds the trailer), never `workit git …`: Claude Code\'s worktree isolation refuses a command that wraps git and cannot be turned off (https://code.claude.com/docs/en/worktrees#how-claude-code-enforces-isolation). Never dodge that check by renaming or re-wrapping git. Use workit for the non-git verbs (`workit check`, `workit ledger`, `workit pr`).';
19426
+ var isolatedGit = (cwd) => `Run git as plain, separate commands inside your worktree (\`git switch -c <branch> <base>\`, ${workspaceTrailers(cwd).enabled ? '`git commit --trailer "Workit-Session=<your session>"`, `git push`; `workit doctor --fix` can install a prepare-commit-msg hook that adds the trailer' : "`git commit` (this workspace sets trailers: false: add no Workit-Session trailer), `git push`"}; add Co-Authored-By with \`git commit --trailer\` in the same commit, never by amending), never \`workit git …\`: Claude Code's worktree isolation refuses a command that wraps git and cannot be turned off (https://code.claude.com/docs/en/worktrees#how-claude-code-enforces-isolation). Never dodge that check by renaming or re-wrapping git. Use workit for the non-git verbs (\`workit check\`, \`workit ledger\`, \`workit pr\`).`;
19406
19427
  var subagentStartText = (input, descriptor, event) => {
19407
19428
  const session = input.session.id ?? null;
19408
19429
  const role = workitRole(descriptor, event.agentType);
@@ -19410,9 +19431,9 @@ var subagentStartText = (input, descriptor, event) => {
19410
19431
  const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer" || CLAUDE_WORKTREE.test(input.cwd));
19411
19432
  const guide = role === "implementer" ? branchGuidance(input.cwd) : null;
19412
19433
  if (role === "implementer" && isolated)
19413
- return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${ISOLATED_GIT} Plain git is expected here, and the branch name is still policy-checked: a raw \`git switch -c\`, \`git checkout -b\`, \`git branch\` or \`git worktree add -b\` onto a protected or non-compliant name is denied, so use a policy-compliant branch.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
19434
+ return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${isolatedGit(input.cwd)} Plain git is expected here, and the branch name is still policy-checked: a raw \`git switch -c\`, \`git checkout -b\`, \`git branch\` or \`git worktree add -b\` onto a protected or non-compliant name is denied, so use a policy-compliant branch.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
19414
19435
  if (isolated)
19415
- return `${ISOLATED_GIT}
19436
+ return `${isolatedGit(input.cwd)}
19416
19437
  ${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
19417
19438
  if (role === "implementer")
19418
19439
  return `Workit observed ${who} as an implementer: it edits and commits only in its own git worktree (the lead makes one with \`workit fanout worktree create <slice>\`), never in the lead's checkout, within its brief's scope. Before the first commit, switch to a policy-compliant branch with \`workit git branch <branch> --base <base>\` (or \`--kind <kind> --slug <slug>\`, which picks the base); branch policy hooks still deny protected or non-compliant branches, raw git included.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-cursor",
3
- "version": "8.11.0",
3
+ "version": "8.12.0",
4
4
  "private": false,
5
5
  "description": "Workit Cursor plugin — shared MCP transport, native hooks, and sixteen method skills",
6
6
  "keywords": [
@@ -46,8 +46,8 @@
46
46
  "build": "bun scripts/build.ts"
47
47
  },
48
48
  "dependencies": {
49
- "@brainervirus/workit-core": "^8.11.0",
50
- "@brainervirus/workit-mcp": "^8.11.0"
49
+ "@brainervirus/workit-core": "^8.12.0",
50
+ "@brainervirus/workit-mcp": "^8.12.0"
51
51
  },
52
52
  "engines": {
53
53
  "node": ">=24"
@@ -25,7 +25,7 @@ REPORT: branch, head SHA, files changed, each VERIFY command with its exit code,
25
25
  each ACCEPTANCE line met / not met, rulings you made (`workit ledger ruling`),
26
26
  anything out of scope as a follow-up, not a diff.
27
27
  STANDING: <the standing orders, verbatim: `workit ledger standing add` records each one>
28
- export WORKIT_SESSION_ID=<lead>-w<n> (set by the lead for a worker's commits; a verifier brief sets none: the host derives it)
28
+ <identity line, per the lead's host: see "Identity and git rules per host" below>
29
29
  ```
30
30
 
31
31
  ## Worked example
@@ -97,17 +97,32 @@ is the slice's STUCK threshold in `workit fanout status`. `"fanIn":
97
97
  }
98
98
  ```
99
99
 
100
+ ## Identity and git rules per host
101
+
102
+ `workit fanout brief` renders the identity line and RULES 1 and 3 for the
103
+ lead's host (`WORKIT_HOST`, or the host's own session variable):
104
+
105
+ | Lead's host | Identity line | RULES 1 and 3 |
106
+ | --- | --- | --- |
107
+ | Claude Code | `Session: your env already has WORKIT_SESSION_ID (the lead's id)`; no `export`, no hand-minted id (SubagentStart issues `<lead>:<agent id>` only to verifiers and reviewers, never to an implementer, so the worker's commits carry the lead's id) | plain git: `git fetch origin && git switch -c <branch> origin/<base>` and `git commit -m <msg> --trailer "Workit-Session: <the env WORKIT_SESSION_ID>" --trailer "<host attribution>" -- <paths in SCOPE>`, because worktree isolation refuses every `workit git` form |
108
+ | OpenCode, Pi, Codex | `Session: your host already sets WORKIT_SESSION_ID in your shell`; export nothing (the host derives the id and an export cannot replace it) | `workit git branch <branch> --base <base>`, `workit git commit -m <msg> -- <paths in SCOPE>` |
109
+ | Cursor, CI, a plain terminal | `export WORKIT_SESSION_ID=<lead>-w-<slice>` (`+try<n>` for a race attempt): declared, not checked | the same `workit git` forms |
110
+
111
+ `MODE: resume` is `git switch <branch>` on every host (the branch exists; the
112
+ lead removed the dead worker's worktree after its exit, so the switch
113
+ succeeds), then continue from its head. A race attempt (`--attempt <n>`)
114
+ follows its host's row with the branch `<branch>-try<n>`.
115
+
100
116
  ## Worker rules (`workit fanout brief` appends them as RULES)
101
117
 
102
- 1. First command. `MODE: new`: `workit git branch <branch> --base <base>` (the
103
- worktree may start on a name that breaks branch policy). `MODE: resume`:
104
- `git switch <branch>` (the branch exists; the lead removed the dead
105
- worker's worktree after its exit, so the switch succeeds), then continue
106
- from its head.
118
+ 1. First command: create the branch (`MODE: new`; the worktree may start on a
119
+ name that breaks branch policy) or `git switch` to it (`MODE: resume`),
120
+ as the table above says for your host.
107
121
  2. Decide ambiguities yourself and record them:
108
122
  `workit ledger ruling "<what>" --why "<why>" --cost-if-wrong "<cost>"`.
109
123
  Stop only for an irreversible action, a security-sensitive one, or a side
110
124
  effect outside the worktree.
111
- 3. Commit with `workit git commit -m "<msg>" -- <paths in SCOPE>`; push only if
112
- the brief says so.
125
+ 3. Commit as the table says (`workit git commit -m "<msg>" -- <paths in SCOPE>`,
126
+ or plain git with the trailers on Claude Code); push only if the brief says
127
+ so.
113
128
  4. Never record a verdict on your own work.
@@ -73,8 +73,8 @@ Which session id a verdict carries, per host:
73
73
  - Claude Code: subagents inherit your `WORKIT_SESSION_ID`, so the
74
74
  SubagentStart hook names each `verifier` and `reviewer` its own session
75
75
  (`<lead>:<agent id>`), passed exactly as `--session`: the hook records the
76
- ids it issues, and only those are accepted. An `implementer` uses the
77
- session its brief exports for its workit commands.
76
+ ids it issues, and only those are accepted. An `implementer` is issued
77
+ none: it keeps your id in its env for its workit commands and commits.
78
78
  - Codex: the `workit-verifier` and `workit-reviewer` agents get the same
79
79
  issued `--session` from SubagentStart; any other verifier passes
80
80
  `--as verifier`.
@@ -84,8 +84,13 @@ Which session id a verdict carries, per host:
84
84
  - Cursor (no session id in the shell): the brief sets the verifier's
85
85
  `WORKIT_SESSION_ID=<lead>:verifier-<random hex>`, a fresh suffix per
86
86
  verifier. Cursor cannot check it: it is declared, not derived.
87
- - A worker's commits use `export WORKIT_SESSION_ID=<lead>-w-<slice>` from
88
- `workit fanout brief`. A verdict under an id you made up (`<lead>-v1`,
87
+ - A worker's commits: on Claude Code the lead's `WORKIT_SESSION_ID` already in
88
+ its env (SubagentStart issues no implementer id; plain git, no export, so the
89
+ lead authored those commits: a verifier or reviewer records the verdict, not
90
+ the lead); on OpenCode, Pi and Codex the id the host already
91
+ puts in its shell; on Cursor, CI and a plain terminal the brief's
92
+ `export WORKIT_SESSION_ID=<lead>-w-<slice>` (see `brief.md`, "Identity and
93
+ git rules per host"). A verdict under an id you made up (`<lead>-v1`,
89
94
  `<lead>:v1`) is refused as `forged_session` on Claude Code, Codex,
90
95
  OpenCode and Pi.
91
96