@fitlab-ai/agent-infra 0.11.4 → 0.11.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/bin/internal-cli.js +0 -5
  2. package/dist/lib/decide.js +4 -41
  3. package/dist/lib/git/branch-worktree.js +45 -0
  4. package/dist/lib/internal/cli-route-inventory.js +0 -3
  5. package/dist/lib/internal/task-activity.js +7 -40
  6. package/dist/lib/internal/task-event.js +4 -37
  7. package/dist/lib/internal/task-finalization.js +9 -2
  8. package/dist/lib/internal/task-ledger.js +5 -43
  9. package/dist/lib/internal/task-lifecycle.js +1 -1
  10. package/dist/lib/internal/task-operation-registry.js +1 -4
  11. package/dist/lib/internal/task-review.js +5 -37
  12. package/dist/lib/internal/task-verify.js +3 -47
  13. package/dist/lib/internal/task-warning.js +4 -40
  14. package/dist/lib/platform/pr-summary.js +4 -23
  15. package/dist/lib/platform/verification-sync.js +12 -49
  16. package/dist/lib/sandbox/control/client.js +4 -1
  17. package/dist/lib/sandbox/control/executor.js +12 -4
  18. package/dist/lib/sandbox/control/protocol.js +2 -1
  19. package/dist/lib/sandbox/removal.js +15 -8
  20. package/dist/lib/task/activity-intent.js +1 -2
  21. package/dist/lib/task/artifact-operations.js +36 -2
  22. package/dist/lib/task/artifact-schema.js +7 -7
  23. package/dist/lib/task/control-authority.js +9 -166
  24. package/dist/lib/task/decision-intents.js +2 -4
  25. package/dist/lib/task/events.js +7 -28
  26. package/dist/lib/task/finalization-handoff.js +92 -0
  27. package/dist/lib/task/finalization.js +123 -12
  28. package/dist/lib/task/intermediate-cleanup.js +9 -148
  29. package/dist/lib/task/ledger-intents.js +3 -6
  30. package/dist/lib/task/lifecycle.js +50 -11
  31. package/dist/lib/task/local-artifact-finalization.js +13 -28
  32. package/dist/lib/task/review-command.js +1 -2
  33. package/dist/lib/task/review-finalization.js +1 -2
  34. package/dist/lib/task/snapshot.js +6 -6
  35. package/dist/lib/task/verification-engine.js +16 -11
  36. package/dist/lib/task/verification.js +1 -13
  37. package/dist/lib/task/workflow-warning-intents.js +2 -4
  38. package/dist/lib/task/write.js +1 -2
  39. package/dist/lifecycle-build-manifest.json +3 -3
  40. package/lib/decide.ts +5 -35
  41. package/lib/git/branch-worktree.ts +41 -0
  42. package/lib/internal/cli-route-inventory.ts +0 -2
  43. package/lib/internal/task-activity.ts +6 -34
  44. package/lib/internal/task-event.ts +4 -37
  45. package/lib/internal/task-finalization.ts +9 -2
  46. package/lib/internal/task-ledger.ts +5 -38
  47. package/lib/internal/task-lifecycle.ts +2 -2
  48. package/lib/internal/task-operation-registry.ts +1 -4
  49. package/lib/internal/task-review.ts +5 -31
  50. package/lib/internal/task-verify.ts +3 -39
  51. package/lib/internal/task-warning.ts +3 -32
  52. package/lib/platform/pr-summary.ts +4 -25
  53. package/lib/platform/verification-sync.ts +13 -53
  54. package/lib/sandbox/control/client.ts +5 -1
  55. package/lib/sandbox/control/executor.ts +13 -4
  56. package/lib/sandbox/control/protocol.ts +3 -2
  57. package/lib/sandbox/removal.ts +23 -7
  58. package/lib/task/activity-intent.ts +1 -2
  59. package/lib/task/artifact-operations.ts +58 -2
  60. package/lib/task/artifact-schema.ts +9 -7
  61. package/lib/task/control-authority.ts +14 -188
  62. package/lib/task/decision-intents.ts +2 -4
  63. package/lib/task/events.ts +8 -27
  64. package/lib/task/finalization-handoff.ts +104 -0
  65. package/lib/task/finalization.ts +120 -12
  66. package/lib/task/intermediate-cleanup.ts +9 -125
  67. package/lib/task/ledger-intents.ts +3 -6
  68. package/lib/task/lifecycle.ts +45 -13
  69. package/lib/task/local-artifact-finalization.ts +16 -35
  70. package/lib/task/review-command.ts +2 -5
  71. package/lib/task/review-finalization.ts +1 -4
  72. package/lib/task/snapshot.ts +6 -6
  73. package/lib/task/verification-engine.ts +20 -10
  74. package/lib/task/verification.ts +1 -15
  75. package/lib/task/workflow-warning-intents.ts +2 -4
  76. package/lib/task/write.ts +1 -4
  77. package/package.json +1 -1
  78. package/templates/.agents/skills/analyze-task/SKILL.en.md +11 -2
  79. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +11 -2
  80. package/templates/.agents/skills/code-task/reference/report-template.en.md +6 -6
  81. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +6 -6
  82. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +2 -2
  83. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +2 -2
  84. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +1 -3
  85. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +1 -3
  86. package/templates/.agents/skills/complete-task/config/verify.en.json +2 -2
  87. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +2 -2
  88. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +3 -3
  89. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +3 -3
  90. package/templates/.agents/skills/review-code/reference/report-template.en.md +3 -3
  91. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +3 -3
  92. package/templates/.agents/skills/review-plan/reference/report-template.en.md +3 -3
  93. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +3 -3
  94. package/templates/.agents/skills/review-pr/config/verify.en.json +3 -1
  95. package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +3 -1
  96. package/templates/.agents/skills/review-pr/reference/report-template.en.md +3 -3
  97. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +3 -3
  98. package/templates/.agents/skills/run-manual-validation/config/verify.en.json +2 -2
  99. package/templates/.agents/skills/run-manual-validation/config/verify.zh-CN.json +2 -2
  100. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +2 -2
  101. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +2 -2
  102. package/dist/lib/internal/task-override.js +0 -138
  103. package/dist/lib/task/artifact-recovery.js +0 -476
  104. package/dist/lib/task/artifact-repair-intent.js +0 -181
  105. package/dist/lib/task/guard-override.js +0 -31
  106. package/dist/lib/task/human-override.js +0 -1259
  107. package/lib/internal/task-override.ts +0 -144
  108. package/lib/task/artifact-recovery.ts +0 -572
  109. package/lib/task/artifact-repair-intent.ts +0 -227
  110. package/lib/task/guard-override.ts +0 -50
  111. package/lib/task/human-override.ts +0 -1522
@@ -56,25 +56,25 @@ function collectTaskSnapshot(taskRef, options = {}) {
56
56
  const observations = [];
57
57
  try {
58
58
  const output = stripOneTrailingNewline((options.gitStatus ?? defaultGitStatus)(resolved.repoRoot));
59
- observations.push({ name: 'git', status: 'ready', command: '$ git status -s', output, error: null });
59
+ observations.push({ name: 'git', status: 'ready', command: 'git status --short --untracked-files=all', output, error: null });
60
60
  }
61
61
  catch (error) {
62
- return failedSnapshot(resolved, taskRef, observations, 'git', '$ git status -s', 'SNAPSHOT_GIT_FAILED', error);
62
+ return failedSnapshot(resolved, taskRef, observations, 'git', 'git status --short --untracked-files=all', 'SNAPSHOT_GIT_FAILED', error);
63
63
  }
64
64
  try {
65
65
  const entries = (options.readDirectory ?? ((dir) => fs.readdirSync(dir, { withFileTypes: true })))(resolved.taskDir);
66
66
  const output = renderDirectory(entries, resolved.taskDir, options.lstat ?? fs.lstatSync);
67
- observations.push({ name: 'task-directory', status: 'ready', command: `$ ls -la ${taskDirPath}/`, output, error: null });
67
+ observations.push({ name: 'task-directory', status: 'ready', command: `fs.readdirSync ${taskDirPath}/`, output, error: null });
68
68
  }
69
69
  catch (error) {
70
- return failedSnapshot(resolved, taskRef, observations, 'task-directory', `$ ls -la ${taskDirPath}/`, 'SNAPSHOT_DIRECTORY_READ_FAILED', error);
70
+ return failedSnapshot(resolved, taskRef, observations, 'task-directory', `fs.readdirSync ${taskDirPath}/`, 'SNAPSHOT_DIRECTORY_READ_FAILED', error);
71
71
  }
72
72
  try {
73
73
  const content = (options.readTask ?? ((file) => fs.readFileSync(file, 'utf8')))(resolved.taskMdPath);
74
- observations.push({ name: 'task-tail', status: 'ready', command: `$ tail ${taskPath}`, output: renderTail(content), error: null });
74
+ observations.push({ name: 'task-tail', status: 'ready', command: `fs.readFileSync ${taskPath} (last 10 lines)`, output: renderTail(content), error: null });
75
75
  }
76
76
  catch (error) {
77
- return failedSnapshot(resolved, taskRef, observations, 'task-tail', `$ tail ${taskPath}`, 'SNAPSHOT_TASK_READ_FAILED', error);
77
+ return failedSnapshot(resolved, taskRef, observations, 'task-tail', `fs.readFileSync ${taskPath} (last 10 lines)`, 'SNAPSHOT_TASK_READ_FAILED', error);
78
78
  }
79
79
  return {
80
80
  status: 'ready', changed: false, requestRef: taskRef, taskId: resolved.taskId,
@@ -11,6 +11,7 @@ import { inspectPlatformPullRequest } from "../platform/pull-requests.js";
11
11
  import { resolveMaterializedReviewedHeadRelation } from "../platform/change-request-git-evidence.js";
12
12
  import { resolveReviewedHeadRelation } from "../platform/merged-pr-equivalence.js";
13
13
  import { resolveLocalReviewedCommitRelation } from "../git/reviewed-commit-equivalence.js";
14
+ import { resolveBranchWorktree } from "../git/branch-worktree.js";
14
15
  import { parseTypedTaskFrontmatter } from "./frontmatter.js";
15
16
  import { LEDGER_TERMINAL, LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from "./ledger.js";
16
17
  import { isValidAgentInfraVersion } from "../version.js";
@@ -483,6 +484,18 @@ function checkArtifact({ taskDir, config, artifactFile, skillName }) {
483
484
  return failResult("artifact", `${path.basename(artifactPath)} is missing required pattern: ${pattern}`);
484
485
  }
485
486
  }
487
+ const stateCheckPatterns = config.state_check_patterns || [];
488
+ if (stateCheckPatterns.length > 0) {
489
+ const scanned = scanVisibleMarkdown(content);
490
+ const stateCheckHeading = scanned.headings.find((heading) => (heading.level === 2 && (heading.text === "状态核对" || heading.text === "State Check")));
491
+ const nextHeading = stateCheckHeading && scanned.headings.find((heading) => (heading.start > stateCheckHeading.start && heading.level <= 2));
492
+ const stateCheckBody = stateCheckHeading ? content.slice(stateCheckHeading.end, nextHeading?.start ?? content.length) : "";
493
+ for (const pattern of stateCheckPatterns) {
494
+ if (!new RegExp(pattern, "m").test(stateCheckBody)) {
495
+ return failResult("artifact", `${path.basename(artifactPath)} state-check section is missing required command: ${pattern}`);
496
+ }
497
+ }
498
+ }
486
499
  return passResult("artifact", `${path.basename(artifactPath)} passed (${requiredSections.length} sections)`);
487
500
  }
488
501
  function checkDecisionDetails({ taskDir, artifactFile }) {
@@ -1078,17 +1091,9 @@ function checkReviewFact({ taskDir, artifactFile, repositoryRoot }) {
1078
1091
  function reviewWorktreeForTask(repositoryRoot, branch) {
1079
1092
  if (!branch)
1080
1093
  return null;
1081
- const expectedRef = `refs/heads/${branch}`;
1082
- const records = execFileSync("git", ["-C", repositoryRoot, "worktree", "list", "--porcelain"], {
1083
- encoding: "utf8",
1084
- stdio: ["pipe", "pipe", "pipe"]
1085
- }).trim().split(/\r?\n\r?\n/);
1086
- for (const record of records) {
1087
- const worktree = /^worktree (.+)$/m.exec(record)?.[1];
1088
- const branchRef = /^branch (.+)$/m.exec(record)?.[1];
1089
- if (worktree && branchRef === expectedRef)
1090
- return worktree;
1091
- }
1094
+ const worktree = resolveBranchWorktree(repositoryRoot, branch);
1095
+ if (worktree)
1096
+ return worktree;
1092
1097
  throw new Error(`Task branch '${branch}' is not checked out in a registered worktree`);
1093
1098
  }
1094
1099
  function resolvePostReviewBaseline({ gitRoot, lastReviewedCommit, reviewArtifact }) {
@@ -4,7 +4,6 @@ import path from 'node:path';
4
4
  import { verifyInProcess } from './verification-engine.js';
5
5
  import { parseArtifactName } from './artifact-name.js';
6
6
  import { resolveTaskRef } from './resolve-ref.js';
7
- import { allowsManualOverride } from './guard-override.js';
8
7
  const gate = (skill, expectedState, artifactFamily) => ({
9
8
  skill, expectedState, mode: 'gate', ...(artifactFamily ? { artifactFamily } : {})
10
9
  });
@@ -50,7 +49,7 @@ async function verifyTaskEvent(request, options = {}) {
50
49
  if (!resolved.ok)
51
50
  return failure(request, resolved.code, resolved.message, { taskId: resolved.taskId, skill: spec.skill, mode: spec.mode });
52
51
  const identity = { taskId: resolved.taskId, taskDir: resolved.taskDir, taskState: resolved.state, skill: spec.skill, mode: spec.mode };
53
- if (resolved.state !== spec.expectedState && !allowsManualOverride(options.manualOverride, 'task-verify', 'VERIFY_TASK_STATE_MISMATCH')) {
52
+ if (resolved.state !== spec.expectedState) {
54
53
  return failure(request, 'VERIFY_TASK_STATE_MISMATCH', `event '${request.event}' requires workspace '${spec.expectedState}', received '${resolved.state}'`, identity);
55
54
  }
56
55
  if (spec.artifactFamily) {
@@ -69,23 +68,12 @@ async function verifyTaskEvent(request, options = {}) {
69
68
  if (spec.mode === 'gate') {
70
69
  const payload = await engine({ mode: 'gate', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [], repositoryRoot: resolved.repoRoot });
71
70
  const status = payload.gate;
72
- if (status !== 'pass' && allowsManualOverride(options.manualOverride, 'verification-engine', status === 'blocked' ? 'CHECK_BLOCKED' : 'CHECK_FAILED')) {
73
- invocations.push({ status: 'pass', exitCode: 0, payload: { ...payload, gate: 'pass', humanOverride: 'human-approved', originalGate: status } });
74
- return {
75
- status: 'pass', changed: false, event: request.event, requestRef: request.taskRef,
76
- ...identity, artifact: request.artifact ?? null, invocations, error: null
77
- };
78
- }
79
71
  invocations.push({ status, exitCode: { pass: 0, fail: 1, blocked: 2 }[status], payload });
80
72
  }
81
73
  else {
82
74
  for (const check of spec.checks ?? []) {
83
75
  const payload = await engine({ mode: 'checks', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [check], repositoryRoot: resolved.repoRoot });
84
76
  const status = (payload.effectiveStatus ?? payload.status);
85
- if (status !== 'pass' && allowsManualOverride(options.manualOverride, 'verification-engine', status === 'blocked' ? 'CHECK_BLOCKED' : 'CHECK_FAILED')) {
86
- invocations.push({ status: 'pass', exitCode: 0, payload: { ...payload, status: 'pass', humanOverride: 'human-approved', originalStatus: status } });
87
- break;
88
- }
89
77
  invocations.push({ status, exitCode: { pass: 0, fail: 1, blocked: 2 }[status], payload });
90
78
  if (status !== 'pass')
91
79
  break;
@@ -3,7 +3,6 @@ import { resolveTaskRef } from './resolve-ref.js';
3
3
  import { parseTaskFrontmatter } from './frontmatter.js';
4
4
  import { WORKFLOW_WARNING_COLUMNS, WORKFLOW_WARNING_HEADINGS, WORKFLOW_WARNING_SEVERITIES, WORKFLOW_WARNING_STATUSES, parseWorkflowWarnings } from './workflow-warnings.js';
5
5
  import { captureTaskWriteMetadata, writeTask } from './write.js';
6
- import { allowsManualOverride } from './guard-override.js';
7
6
  import { retryHintForWarning } from './operation-outcome.js';
8
7
  function failed(intent, code, message, taskId = null, entityId = null) {
9
8
  return { status: 'failed', changed: false, intent: intent.kind, taskId, entityId, before: null, after: null, warnings: [], operations: [], error: { code, message } };
@@ -44,8 +43,7 @@ function applyWorkflowWarningIntent(intent, options = {}) {
44
43
  const resolved = resolveTaskRef(intent.taskRef, { repoRoot: options.repoRoot });
45
44
  if (!resolved.ok)
46
45
  return failed(intent, resolved.code, resolved.message, resolved.taskId);
47
- const stateOverride = allowsManualOverride(options.manualOverride, 'workflow-warning', 'TASK_STATE_MISMATCH');
48
- if (resolved.state !== 'active' && !stateOverride)
46
+ if (resolved.state !== 'active')
49
47
  return failed(intent, 'TASK_STATE_MISMATCH', `task ${resolved.taskId} is ${resolved.state}, expected active`, resolved.taskId);
50
48
  let content;
51
49
  let rows;
@@ -102,7 +100,7 @@ function applyWorkflowWarningIntent(intent, options = {}) {
102
100
  after = { ...before, status: intent.status, resolvedAt: metadata.timestamp, resolution };
103
101
  }
104
102
  const writeResult = writeTask({
105
- taskRef: intent.taskRef, expectedState: stateOverride ? resolved.state : 'active', mutations: [...sectionMutation(content), rowMutation(after)], dryRun: intent.dryRun
103
+ taskRef: intent.taskRef, expectedState: 'active', mutations: [...sectionMutation(content), rowMutation(after)], dryRun: intent.dryRun
106
104
  }, {
107
105
  ...options,
108
106
  taskLocation: { repoRoot: resolved.repoRoot, taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, state: resolved.state },
@@ -3,7 +3,6 @@ import path from 'node:path';
3
3
  import { isValidAgentInfraVersion, VERSION } from '../version.js';
4
4
  import { parseTypedTaskFrontmatter, updateTaskFrontmatter } from './frontmatter.js';
5
5
  import { resolveTaskRef } from './resolve-ref.js';
6
- import { allowsManualOverride } from './guard-override.js';
7
6
  import { mutateTableRow, upsertSection } from './sections.js';
8
7
  import { validateCurrentTaskContract } from './current-contract.js';
9
8
  import { invalidationBlocks, parseInvalidationDocument } from './invalidation.js';
@@ -73,7 +72,7 @@ function writeTask(request, options = {}) {
73
72
  taskMdPath: resolved.taskMdPath,
74
73
  actualState: resolved.state
75
74
  };
76
- if (resolved.state !== request.expectedState && !allowsManualOverride(options.manualOverride, 'task.write', 'TASK_STATE_MISMATCH')) {
75
+ if (resolved.state !== request.expectedState) {
77
76
  return failure(request, identity, 'TASK_STATE_MISMATCH', `task ${resolved.taskId} is ${resolved.state}, expected ${request.expectedState}`);
78
77
  }
79
78
  const io = { ...DEFAULT_FILE_SYSTEM, ...options.fileSystem };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "protocolVersion": 3,
3
- "packageVersion": "0.11.4",
4
- "sourceInputHash": "46c0a39f354bff8c80fe19354cdda89a91a4acad060b1f134b6d599bc0ba6806",
5
- "internalExecutableBuildHash": "1bc9e5755c857ee9f13a702452b2ce7c85da94444dc5a8d1305ae80d5899b001"
3
+ "packageVersion": "0.11.5",
4
+ "sourceInputHash": "2f29b7f1f134733c3bc1bb7c92ea6c11e57462ed51a5a96b0198b8824a3f455d",
5
+ "internalExecutableBuildHash": "cb9d00aa3fa974cf936a8aad310e1fa5f28842351f52a53fed43345fe9c46439"
6
6
  }
package/lib/decide.ts CHANGED
@@ -2,7 +2,6 @@ import { VERSION } from './version.ts';
2
2
  import { parseTaskScope } from './task/command-options.ts';
3
3
  import { applyHumanDecision } from './task/decision-intents.ts';
4
4
  import { canonicalTimestamp } from './task/write.ts';
5
- import { consumeHumanOverride, failureId } from './task/human-override.ts';
6
5
  import { resolveTaskContext } from './task/resolve-ref.ts';
7
6
  import { TaskExecutionLockError, withTaskExecutionLock } from './task/task-execution-lock.ts';
8
7
 
@@ -12,12 +11,9 @@ type DecideOptions = {
12
11
  version?: string;
13
12
  };
14
13
 
15
- function parseDecisionParts(parts: string[]): { decision: string; needsImplementation: boolean | undefined; overrideTicket?: string; overrideTarget?: string; overrideScope?: string } {
14
+ function parseDecisionParts(parts: string[]): { decision: string; needsImplementation: boolean | undefined } {
16
15
  const decision: string[] = [];
17
16
  let needsImplementation: boolean | undefined;
18
- let overrideTicket: string | undefined;
19
- let overrideTarget: string | undefined;
20
- let overrideScope: string | undefined;
21
17
  for (let index = 0; index < parts.length; index += 1) {
22
18
  const part = parts[index];
23
19
  if (part === '--needs-implementation') {
@@ -27,18 +23,14 @@ function parseDecisionParts(parts: string[]): { decision: string; needsImplement
27
23
  throw new Error("--needs-implementation must be 'true' or 'false'");
28
24
  }
29
25
  needsImplementation = value === 'true';
30
- } else if (part === '--override-ticket' || part === '--override-target' || part === '--override-scope') {
31
- const value = parts[++index];
32
- if (!value) throw new Error(`${part} requires a value`);
33
- if (part === '--override-ticket') overrideTicket = value;
34
- else if (part === '--override-target') overrideTarget = value;
35
- else overrideScope = value;
26
+ } else if (part?.startsWith('--')) {
27
+ throw new Error(`unknown option '${part}'`);
36
28
  } else {
37
29
  decision.push(parts[index]!);
38
30
  }
39
31
  }
40
32
  if (decision.length === 0) throw new Error('decision content is required');
41
- return { decision: decision.join(' '), needsImplementation, overrideTicket, overrideTarget, overrideScope };
33
+ return { decision: decision.join(' '), needsImplementation };
42
34
  }
43
35
 
44
36
  export async function decide(args: string[], options: DecideOptions = {}): Promise<number> {
@@ -79,29 +71,7 @@ export async function decide(args: string[], options: DecideOptions = {}): Promi
79
71
  metadataProvider: () => ({ timestamp: now, agentInfraVersion: options.version ?? VERSION })
80
72
  };
81
73
  let result;
82
- const execute = async () => {
83
- let current = applyHumanDecision(request, writeOptions);
84
- if (current.status !== 'failed' || !parsedDecision.overrideTicket) return current;
85
- if (!parsedDecision.overrideTarget || !parsedDecision.overrideScope) throw new Error('override ticket requires --override-target and --override-scope');
86
- const consumed = await consumeHumanOverride({
87
- taskRef: resolved.taskId,
88
- ticketId: parsedDecision.overrideTicket,
89
- failureId: failureId('decision-intent', current.error?.code ?? 'TASK_STATE_MISMATCH'),
90
- target: parsedDecision.overrideTarget,
91
- scope: parsedDecision.overrideScope
92
- }, {
93
- ...writeOptions,
94
- effectExecutor: (capability) => {
95
- const retried = applyHumanDecision(request, { ...writeOptions, manualOverride: capability });
96
- current = retried;
97
- return retried.status === 'failed' || retried.status === 'planned'
98
- ? { code: 'OVERRIDE_EFFECT_FAILED', message: retried.status === 'planned' ? 'producer returned planned; no decision effect was committed' : `${retried.error?.code ?? 'DECISION_FAILED'}: ${retried.error?.message ?? 'manual decision effect failed'}` }
99
- : null;
100
- }
101
- });
102
- if (consumed.status === 'failed') throw new Error(consumed.error.message);
103
- return current;
104
- };
74
+ const execute = async () => applyHumanDecision(request, writeOptions);
105
75
  result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-decision', execute);
106
76
  if (result.error) throw new Error(result.error.message);
107
77
  return 0;
@@ -0,0 +1,41 @@
1
+ import { execFileSync } from 'node:child_process';
2
+
3
+ function gitText(repositoryRoot: string, args: string[]): string | null {
4
+ try {
5
+ return execFileSync('git', ['-C', repositoryRoot, ...args], {
6
+ encoding: 'utf8',
7
+ stdio: ['ignore', 'pipe', 'pipe']
8
+ }).trim();
9
+ } catch {
10
+ return null;
11
+ }
12
+ }
13
+
14
+ function verifiedWorktreeRoot(candidate: string, expectedBranch: string, expectedCommonDirectory: string): string | null {
15
+ const commonDirectory = gitText(candidate, ['rev-parse', '--path-format=absolute', '--git-common-dir']);
16
+ if (commonDirectory !== expectedCommonDirectory) return null;
17
+ const root = gitText(candidate, ['rev-parse', '--show-toplevel']);
18
+ if (!root) return null;
19
+ const branch = gitText(root, ['symbolic-ref', '--short', 'HEAD']);
20
+ return branch === expectedBranch ? root : null;
21
+ }
22
+
23
+ export function resolveBranchWorktree(repositoryRoot: string, expectedBranch: string): string | null {
24
+ const commonDirectory = gitText(repositoryRoot, ['rev-parse', '--path-format=absolute', '--git-common-dir']);
25
+ if (!commonDirectory) return null;
26
+ const currentRoot = verifiedWorktreeRoot(repositoryRoot, expectedBranch, commonDirectory);
27
+ if (currentRoot) return currentRoot;
28
+
29
+ const records = gitText(repositoryRoot, ['worktree', 'list', '--porcelain']);
30
+ if (!records) return null;
31
+ const expectedRef = `refs/heads/${expectedBranch}`;
32
+ for (const record of records.split(/\r?\n\r?\n/)) {
33
+ const candidate = /^worktree (.+)$/m.exec(record)?.[1];
34
+ const branch = /^branch (.+)$/m.exec(record)?.[1];
35
+ if (candidate && branch === expectedRef) {
36
+ const verifiedRoot = verifiedWorktreeRoot(candidate, expectedBranch, commonDirectory);
37
+ if (verifiedRoot) return verifiedRoot;
38
+ }
39
+ }
40
+ return null;
41
+ }
@@ -61,7 +61,6 @@ export const INTERNAL_HANDLER_ROUTE_SELECTORS = Object.freeze({
61
61
  'task-review': ['preflight', 'finalize-summary'],
62
62
  'task-event': ['event'],
63
63
  'task-invalidation': ['reconcile'],
64
- 'task-override': ['diagnose', 'issue', 'consume'],
65
64
  'task-lifecycle': ['intent'],
66
65
  'task-finalization': ['complete'],
67
66
  'task-short-id': ['list', 'list-verify', 'alloc', 'release', 'resolve'],
@@ -98,7 +97,6 @@ export function internalRouteSelector(command: string, args: readonly string[]):
98
97
  if (command === 'task-orchestration') return args[1] === 'status' ? 'status' : args[1] ? 'progress' : '';
99
98
  if (command === 'task-review') return args[1] ?? '';
100
99
  if (command === 'task-invalidation') return args[1] ?? '';
101
- if (command === 'task-override') return args[1] ?? '';
102
100
  if (command === 'task-artifact') return args[1] ?? '';
103
101
  if (command === 'platform-pr-review' && first(args) === 'publish') {
104
102
  const scope = optionValue(args, '--scope') ?? '';
@@ -6,7 +6,6 @@ import type {
6
6
  PrReviewActivityIntent,
7
7
  PrReviewInspectIntent
8
8
  } from '../task/activity-intent.ts';
9
- import { consumeHumanOverride, failureId, overrideDryRunConflict } from '../task/human-override.ts';
10
9
  import { resolveTaskRef } from '../task/resolve-ref.ts';
11
10
  import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
12
11
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
@@ -28,14 +27,13 @@ const FLAGS: Record<string, string> = {
28
27
  '--minor': 'minor',
29
28
  '--outcome': 'outcome',
30
29
  '--reason': 'reason'
31
- , '--override-ticket': 'overrideTicket', '--override-target': 'overrideTarget', '--override-scope': 'overrideScope'
32
30
  };
33
31
  const COMMON = ['agent', 'artifact', 'head'] as const;
34
32
  const ALLOWED: Record<string, ReadonlySet<string>> = {
35
33
  'pr-review-inspect': new Set(['kind', 'taskRef']),
36
- 'pr-review-start': new Set(['kind', 'taskRef', 'agent', 'artifact', 'head', 'dryRun', 'overrideTicket', 'overrideTarget', 'overrideScope']),
37
- 'pr-review-complete': new Set(['kind', 'taskRef', 'agent', 'artifact', 'head', 'verdict', 'blockers', 'major', 'minor', 'dryRun', 'overrideTicket', 'overrideTarget', 'overrideScope']),
38
- 'pr-review-terminate': new Set(['kind', 'taskRef', 'agent', 'artifact', 'head', 'outcome', 'reason', 'dryRun', 'overrideTicket', 'overrideTarget', 'overrideScope'])
34
+ 'pr-review-start': new Set(['kind', 'taskRef', 'agent', 'artifact', 'head', 'dryRun']),
35
+ 'pr-review-complete': new Set(['kind', 'taskRef', 'agent', 'artifact', 'head', 'verdict', 'blockers', 'major', 'minor', 'dryRun']),
36
+ 'pr-review-terminate': new Set(['kind', 'taskRef', 'agent', 'artifact', 'head', 'outcome', 'reason', 'dryRun'])
39
37
  };
40
38
 
41
39
  function usageFailure(message: string): void {
@@ -95,45 +93,19 @@ async function taskActivity(args: string[] = []): Promise<void> {
95
93
  for (const key of operationRequired) {
96
94
  if (values[key] === undefined) { usageFailure(`${kind} requires '${key}'`); return; }
97
95
  }
98
- const dryRunConflict = overrideDryRunConflict(values);
99
- if (dryRunConflict) { usageFailure(dryRunConflict.message); return; }
100
96
  const resolved = resolveTaskRef(taskRef);
101
97
  if (!resolved.ok) { usageFailure(resolved.message); return; }
102
98
  let result;
103
- let humanOverride: unknown = null;
104
99
  try {
105
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-activity.${kind}`, async () => {
106
- let current = applyPrReviewActivityIntent(values as PrReviewActivityIntent, { lockAlreadyHeld: true });
107
- if (current.status !== 'failed' || !values.overrideTicket) return current;
108
- if (!values.overrideTarget || !values.overrideScope) { usageFailure('override ticket requires target and scope'); return current; }
109
- const consumed = await consumeHumanOverride({
110
- taskRef, ticketId: String(values.overrideTicket),
111
- failureId: failureId('activity-intent', current.error?.code ?? 'TASK_STATE_MISMATCH'),
112
- target: String(values.overrideTarget), scope: String(values.overrideScope)
113
- }, {
114
- effectExecutor: (capability) => {
115
- const retried = applyPrReviewActivityIntent(values as PrReviewActivityIntent, { lockAlreadyHeld: true, manualOverride: capability });
116
- current = retried;
117
- return retried.status === 'failed' || retried.status === 'planned'
118
- ? { code: 'OVERRIDE_EFFECT_FAILED', message: retried.status === 'planned' ? 'producer returned planned; no activity effect was committed' : `${retried.error?.code ?? 'ACTIVITY_FAILED'}: ${retried.error?.message ?? 'manual activity effect failed'}` }
119
- : null;
120
- }
121
- });
122
- humanOverride = consumed;
123
- return current;
124
- });
100
+ result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-activity.${kind}`, async () => applyPrReviewActivityIntent(values as PrReviewActivityIntent, { lockAlreadyHeld: true }));
125
101
  } catch (error) {
126
102
  if (!(error instanceof TaskExecutionLockError)) throw error;
127
103
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
128
104
  process.exitCode = 1;
129
105
  return;
130
106
  }
131
- process.stdout.write(`${JSON.stringify(humanOverride ? { ...result, humanOverride } : result)}\n`);
132
- const overrideFailed = Boolean(
133
- humanOverride && typeof humanOverride === 'object' &&
134
- (humanOverride as { status?: unknown }).status === 'failed'
135
- );
136
- if (result.status === 'failed' || overrideFailed) process.exitCode = 1;
107
+ process.stdout.write(`${JSON.stringify(result)}\n`);
108
+ if (result.status === 'failed') process.exitCode = 1;
137
109
  }
138
110
 
139
111
  export { taskActivity };
@@ -1,7 +1,6 @@
1
1
  import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.ts';
2
2
  import { applyTaskEvent, eventCatalog } from '../task/events.ts';
3
3
  import type { TaskEventRequest, Verdict } from '../task/events.ts';
4
- import { consumeHumanOverride, failureId, overrideDryRunConflict } from '../task/human-override.ts';
5
4
  import { resolveTaskRef } from '../task/resolve-ref.ts';
6
5
  import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
7
6
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
@@ -21,8 +20,7 @@ const FLAGS: Record<string, keyof TaskEventRequest> = {
21
20
  '--verdict': 'verdict', '--blockers': 'blockers', '--major': 'major',
22
21
  '--minor': 'minor', '--manual-validation': 'manualValidation', '--files-modified': 'filesModified',
23
22
  '--tests-passed': 'testsPassed', '--summary-result': 'summaryResult',
24
- '--transaction-id': 'transactionId', '--receipt-digest': 'receiptDigest', '--pr-head-sha': 'prHeadSha',
25
- '--override-ticket': 'overrideTicket', '--override-target': 'overrideTarget', '--override-scope': 'overrideScope'
23
+ '--transaction-id': 'transactionId', '--receipt-digest': 'receiptDigest', '--pr-head-sha': 'prHeadSha'
26
24
  };
27
25
  const NUMERIC = new Set(['round', 'question', 'blockers', 'major', 'minor', 'manualValidation', 'filesModified', 'testsPassed']);
28
26
 
@@ -59,8 +57,6 @@ export function parseTaskEventRequest(args: readonly string[]): TaskEventRequest
59
57
  const agent = normalizeAgentToken(String(request.agent ?? ''));
60
58
  if (!agent) throw new Error(`invalid --agent '${request.agent}': ${AGENT_USAGE_HINT}`);
61
59
  request.agent = agent;
62
- const dryRunConflict = overrideDryRunConflict(request as unknown as Record<string, unknown>);
63
- if (dryRunConflict) throw new Error(dryRunConflict.message);
64
60
  return request;
65
61
  }
66
62
 
@@ -78,45 +74,16 @@ async function taskEvent(args: string[] = []): Promise<void> {
78
74
  return;
79
75
  }
80
76
  let result;
81
- let humanOverride: unknown = null;
82
77
  try {
83
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-event.${request.event}`, async () => {
84
- let current = applyTaskEvent(request, { lockAlreadyHeld: true });
85
- const values = request as Record<string, unknown>;
86
- if (current.status !== 'failed' || !values.overrideTicket) return current;
87
- if (!values.overrideTarget || !values.overrideScope) {
88
- return { ...current, humanOverride: { status: 'failed', error: { code: 'OVERRIDE_PAYLOAD_INVALID', message: 'override ticket requires target and scope' } } } as typeof current & { humanOverride: unknown };
89
- }
90
- const consumed = await consumeHumanOverride({
91
- taskRef: request.taskRef,
92
- ticketId: String(values.overrideTicket),
93
- failureId: failureId('task-event', current.error?.code ?? 'EVENT_TRANSITION_INVALID'),
94
- target: String(values.overrideTarget),
95
- scope: String(values.overrideScope)
96
- }, {
97
- effectExecutor: (capability) => {
98
- const retried = applyTaskEvent(request, { lockAlreadyHeld: true, manualOverride: capability });
99
- current = retried;
100
- return retried.status === 'failed' || retried.status === 'planned'
101
- ? { code: 'OVERRIDE_EFFECT_FAILED', message: retried.status === 'planned' ? 'producer returned planned; no task event was committed' : `${retried.error?.code ?? 'EVENT_FAILED'}: ${retried.error?.message ?? 'manual task event effect failed'}` }
102
- : null;
103
- }
104
- });
105
- humanOverride = consumed;
106
- return current;
107
- });
78
+ result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-event.${request.event}`, async () => applyTaskEvent(request, { lockAlreadyHeld: true }));
108
79
  } catch (error) {
109
80
  if (!(error instanceof TaskExecutionLockError)) throw error;
110
81
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
111
82
  process.exitCode = 1;
112
83
  return;
113
84
  }
114
- process.stdout.write(`${JSON.stringify(humanOverride ? { ...result, humanOverride } : result)}\n`);
115
- const overrideFailed = Boolean(
116
- humanOverride && typeof humanOverride === 'object' &&
117
- (humanOverride as { status?: unknown }).status === 'failed'
118
- );
119
- if (result.status === 'failed' || overrideFailed) process.exitCode = 1;
85
+ process.stdout.write(`${JSON.stringify(result)}\n`);
86
+ if (result.status === 'failed') process.exitCode = 1;
120
87
  }
121
88
 
122
89
  export { taskEvent };
@@ -3,7 +3,8 @@ import {
3
3
  dispatchTaskControlOperation,
4
4
  parseTaskControlOperation
5
5
  } from '../task/control-authority.ts';
6
- import { applyTaskFinalization, prepareTaskFinalization } from '../task/finalization.ts';
6
+ import { applyTaskFinalization, bindTaskFinalizationReceipt, prepareTaskFinalization } from '../task/finalization.ts';
7
+ import { publishTaskFinalizationHandoff } from '../task/finalization-handoff.ts';
7
8
  import { detectRepoRoot, resolveTaskRef } from '../task/resolve-ref.ts';
8
9
  import { verifyTaskEvent } from '../task/verification.ts';
9
10
  import { resolveSandboxControlTransport } from './task-operation-registry.ts';
@@ -88,7 +89,13 @@ async function taskFinalization(args: string[] = []): Promise<void> {
88
89
  return;
89
90
  }
90
91
  try {
91
- const response = requestSandboxTaskFinalization({ agent: boundOperation.request.agent });
92
+ const response = requestSandboxTaskFinalization({
93
+ agent: boundOperation.request.agent,
94
+ prepareHandoff: (binding) => {
95
+ const receipt = bindTaskFinalizationReceipt(repoRoot, boundOperation.request.taskRef, binding);
96
+ return publishTaskFinalizationHandoff('/share/branch', receipt, binding);
97
+ }
98
+ });
92
99
  process.stdout.write(response.stdout);
93
100
  process.stderr.write(response.stderr);
94
101
  process.exitCode = response.exitCode ?? 1;
@@ -2,7 +2,6 @@ import fs from 'node:fs';
2
2
 
3
3
  import { applyLedgerIntent } from '../task/ledger-intents.ts';
4
4
  import type { LedgerIntent } from '../task/ledger-intents.ts';
5
- import { consumeHumanOverride, failureId, overrideDryRunConflict } from '../task/human-override.ts';
6
5
  import { LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, isReviewStage, parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from '../task/ledger.ts';
7
6
  import { resolveTaskRef } from '../task/resolve-ref.ts';
8
7
  import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
@@ -14,8 +13,7 @@ const FLAGS: Record<string, string> = {
14
13
  '--severity': 'severity', '--evidence': 'evidence', '--id': 'id', '--round': 'round',
15
14
  '--status': 'status', '--artifact': 'artifact', '--needs-implementation': 'needsImplementation',
16
15
  '--intent-id': 'intentId', '--finding-id': 'findingId', '--source-artifact': 'sourceArtifact',
17
- '--source-sha256': 'sourceSha256', '--classification': 'classification',
18
- '--override-ticket': 'overrideTicket', '--override-target': 'overrideTarget', '--override-scope': 'overrideScope'
16
+ '--source-sha256': 'sourceSha256', '--classification': 'classification'
19
17
  };
20
18
  const NUMERIC = new Set(['ordinal', 'round']);
21
19
  const BOOLEAN = new Set(['needsImplementation']);
@@ -78,16 +76,11 @@ async function taskLedger(args: string[] = []): Promise<void> {
78
76
  'decision-upsert': ['needsImplementation'],
79
77
  'rework-intent-rebuild': ['findingId', 'sourceArtifact', 'sourceSha256', 'classification']
80
78
  };
81
- const overrideFields = kind === 'stage-status' || kind === 'decision-next-id' || kind === 'rework-intent-upsert' || kind === 'rework-intent-rebuild'
82
- ? []
83
- : ['overrideTicket', 'overrideTarget', 'overrideScope'];
84
- const allowed = new Set(['kind', 'taskRef', 'dryRun', ...required[kind]!, ...(optional[kind] ?? []), ...overrideFields]);
79
+ const allowed = new Set(['kind', 'taskRef', 'dryRun', ...required[kind]!, ...(optional[kind] ?? [])]);
85
80
  const unexpected = Object.keys(values).find((key) => !allowed.has(key));
86
81
  const missing = required[kind]!.find((key) => values[key] === undefined);
87
82
  if (unexpected) { usageFailure(`${kind} does not accept '${unexpected}'`); return; }
88
83
  if (missing) { usageFailure(`${kind} requires '${missing}'`); return; }
89
- const dryRunConflict = overrideDryRunConflict(values);
90
- if (dryRunConflict) { usageFailure(dryRunConflict.message); return; }
91
84
  if (values.classification !== undefined && !REWORK_CLASSIFICATIONS.has(String(values.classification))) {
92
85
  usageFailure(`invalid rework classification '${values.classification}'`); return;
93
86
  }
@@ -124,42 +117,16 @@ async function taskLedger(args: string[] = []): Promise<void> {
124
117
  const lockResolved = resolveTaskRef(taskRef);
125
118
  if (!lockResolved.ok) { usageFailure(lockResolved.message); return; }
126
119
  let result;
127
- let humanOverride: unknown = null;
128
120
  try {
129
- result = await withTaskExecutionLock(lockResolved.repoRoot, lockResolved.taskId, `task-ledger.${kind}`, async () => {
130
- let current = applyLedgerIntent(values as LedgerIntent);
131
- if (current.status !== 'failed' || !values.overrideTicket) return current;
132
- if (!values.overrideTarget || !values.overrideScope) { usageFailure('override ticket requires target and scope'); return current; }
133
- const consumed = await consumeHumanOverride({
134
- taskRef,
135
- ticketId: String(values.overrideTicket),
136
- failureId: failureId('ledger-intent', current.error?.code ?? 'TASK_STATE_MISMATCH'),
137
- target: String(values.overrideTarget),
138
- scope: String(values.overrideScope)
139
- }, {
140
- effectExecutor: (capability) => {
141
- const retried = applyLedgerIntent(values as LedgerIntent, { manualOverride: capability });
142
- current = retried;
143
- return retried.status === 'failed'
144
- ? { code: 'OVERRIDE_EFFECT_FAILED', message: `${retried.error?.code ?? 'LEDGER_FAILED'}: ${retried.error?.message ?? 'manual ledger effect failed'}` }
145
- : null;
146
- }
147
- });
148
- humanOverride = consumed;
149
- return current;
150
- });
121
+ result = await withTaskExecutionLock(lockResolved.repoRoot, lockResolved.taskId, `task-ledger.${kind}`, async () => applyLedgerIntent(values as LedgerIntent));
151
122
  } catch (error) {
152
123
  if (!(error instanceof TaskExecutionLockError)) throw error;
153
124
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
154
125
  process.exitCode = 1;
155
126
  return;
156
127
  }
157
- process.stdout.write(`${JSON.stringify(humanOverride ? { ...result, humanOverride } : result)}\n`);
158
- const overrideFailed = Boolean(
159
- humanOverride && typeof humanOverride === 'object' &&
160
- (humanOverride as { status?: unknown }).status === 'failed'
161
- );
162
- if (result.status === 'failed' || overrideFailed) process.exitCode = 1;
128
+ process.stdout.write(`${JSON.stringify(result)}\n`);
129
+ if (result.status === 'failed') process.exitCode = 1;
163
130
  }
164
131
 
165
132
  export { taskLedger };
@@ -10,7 +10,7 @@ import type { TaskLifecycleResult } from '../task/lifecycle.ts';
10
10
  import type { AgentClientLifecycleRecoveryResult as LifecycleRecoveryResult } from '../agent-clients/adapter.ts';
11
11
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
12
12
 
13
- const USAGE = `Usage: agent-infra-internal task-lifecycle <N | TASK-id> <intent> --agent <agent> [intent flags] [--dry-run]\n\nIntents: ${lifecycleIntentCatalog.join(', ')}\nrecover-started: --auto\nOverride: --override-ticket <ticket> --override-target <target> --override-scope <scope>\n`;
13
+ const USAGE = `Usage: agent-infra-internal task-lifecycle <N | TASK-id> <intent> --agent <agent> [intent flags] [--dry-run]\n\nIntents: ${lifecycleIntentCatalog.join(', ')}\nrecover-started: --auto\n`;
14
14
 
15
15
  function usageFailure(message: string): void {
16
16
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'LIFECYCLE_PAYLOAD_INVALID', message } })}\n`);
@@ -62,7 +62,7 @@ async function taskLifecycle(args: string[] = []): Promise<void> {
62
62
  const result = await dispatchTaskControlOperation(
63
63
  createDirectHostExecutionContext({ repoRoot }),
64
64
  operation
65
- ) as (TaskLifecycleResult | LifecycleRecoveryResult) & { humanOverride?: unknown };
65
+ ) as TaskLifecycleResult | LifecycleRecoveryResult;
66
66
  process.stdout.write(`${JSON.stringify(result)}\n`);
67
67
  if (result.status === 'failed' || result.status === 'owner-unknown' || result.status === 'conflict') process.exitCode = 1;
68
68
  }
@@ -143,9 +143,6 @@ function internalTaskRoutes(): TaskOperationDescriptor[] {
143
143
  descriptor('internal', 'task-review', 'finalize-summary', 'task-bound', 'progress'),
144
144
  descriptor('internal', 'task-event', 'event', 'task-bound', 'progress'),
145
145
  descriptor('internal', 'task-invalidation', 'reconcile', 'task-bound', 'progress'),
146
- descriptor('internal', 'task-override', 'diagnose', 'task-bound', 'diagnostic'),
147
- descriptor('internal', 'task-override', 'issue', 'task-bound', 'progress'),
148
- descriptor('internal', 'task-override', 'consume', 'task-bound', 'progress'),
149
146
  descriptor('internal', 'task-lifecycle', 'intent', 'task-bound', 'progress'),
150
147
  descriptor('internal', 'task-finalization', 'complete', 'task-bound', 'progress'),
151
148
  descriptor('internal', 'task-short-id', 'list', 'conditional', 'diagnostic'),
@@ -224,7 +221,7 @@ export const INTERNAL_DISPATCHER_ROUTES = Object.freeze([
224
221
  'platform-comment', 'platform-issue', 'platform-pr', 'platform-pr-review', 'pr-review-grade',
225
222
  'platform-checks', 'task-context', 'task-ledger', 'task-warning', 'task-activity', 'task-artifact',
226
223
  'task-orchestration', 'task-review', 'task-event', 'task-invalidation', 'task-lifecycle',
227
- 'task-finalization', 'task-override', 'task-short-id', 'task-snapshot', 'task-verify', 'task-validate', 'manual-validation'
224
+ 'task-finalization', 'task-short-id', 'task-snapshot', 'task-verify', 'task-validate', 'manual-validation'
228
225
  ]);
229
226
  export const PUBLIC_DISPATCHER_ROUTES = Object.freeze([
230
227
  'agent-client', 'cp', 'data', 'decide', 'help', 'init', 'merge', 'run', 'sandbox', 'server', 'task', 'sync', 'update', 'version'