@fitlab-ai/agent-infra 0.11.4 → 0.11.6

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 (149) 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/merge.js +62 -10
  15. package/dist/lib/platform/github-provider.js +9 -14
  16. package/dist/lib/platform/github-release-notes.js +80 -11
  17. package/dist/lib/platform/none-provider.js +1 -1
  18. package/dist/lib/platform/pr-summary.js +4 -23
  19. package/dist/lib/platform/provider-contract.d.ts +39 -16
  20. package/dist/lib/platform/provider-contract.js +1 -1
  21. package/dist/lib/platform/provider-validation.js +83 -13
  22. package/dist/lib/platform/release-notes.js +7 -8
  23. package/dist/lib/platform/verification-sync.js +12 -49
  24. package/dist/lib/sandbox/capture.js +1 -1
  25. package/dist/lib/sandbox/commands/create.js +46 -1
  26. package/dist/lib/sandbox/commands/enter.js +1 -1
  27. package/dist/lib/sandbox/commands/start.js +1 -1
  28. package/dist/lib/sandbox/config.js +10 -0
  29. package/dist/lib/sandbox/control/client.js +4 -1
  30. package/dist/lib/sandbox/control/executor.js +12 -4
  31. package/dist/lib/sandbox/control/lifecycle.js +18 -13
  32. package/dist/lib/sandbox/control/protocol.js +2 -1
  33. package/dist/lib/sandbox/removal.js +15 -8
  34. package/dist/lib/sandbox/task-resolver.js +62 -2
  35. package/dist/lib/task/activity-intent.js +1 -2
  36. package/dist/lib/task/artifact-operations.js +36 -2
  37. package/dist/lib/task/artifact-schema.js +7 -7
  38. package/dist/lib/task/control-authority.js +9 -166
  39. package/dist/lib/task/decision-intents.js +2 -4
  40. package/dist/lib/task/events.js +7 -28
  41. package/dist/lib/task/finalization-handoff.js +92 -0
  42. package/dist/lib/task/finalization.js +123 -12
  43. package/dist/lib/task/intermediate-cleanup.js +9 -148
  44. package/dist/lib/task/ledger-intents.js +3 -6
  45. package/dist/lib/task/lifecycle.js +50 -11
  46. package/dist/lib/task/local-artifact-finalization.js +13 -28
  47. package/dist/lib/task/resolve-ref.js +3 -3
  48. package/dist/lib/task/review-command.js +1 -2
  49. package/dist/lib/task/review-finalization.js +1 -2
  50. package/dist/lib/task/snapshot.js +6 -6
  51. package/dist/lib/task/verification-engine.js +16 -11
  52. package/dist/lib/task/verification.js +1 -13
  53. package/dist/lib/task/workflow-warning-intents.js +2 -4
  54. package/dist/lib/task/write.js +122 -3
  55. package/dist/lifecycle-build-manifest.json +3 -3
  56. package/lib/decide.ts +5 -35
  57. package/lib/git/branch-worktree.ts +41 -0
  58. package/lib/internal/cli-route-inventory.ts +0 -2
  59. package/lib/internal/task-activity.ts +6 -34
  60. package/lib/internal/task-event.ts +4 -37
  61. package/lib/internal/task-finalization.ts +9 -2
  62. package/lib/internal/task-ledger.ts +5 -38
  63. package/lib/internal/task-lifecycle.ts +2 -2
  64. package/lib/internal/task-operation-registry.ts +1 -4
  65. package/lib/internal/task-review.ts +5 -31
  66. package/lib/internal/task-verify.ts +3 -39
  67. package/lib/internal/task-warning.ts +3 -32
  68. package/lib/merge.ts +59 -10
  69. package/lib/platform/github-provider.ts +11 -18
  70. package/lib/platform/github-release-notes.ts +89 -14
  71. package/lib/platform/none-provider.ts +1 -1
  72. package/lib/platform/pr-summary.ts +4 -25
  73. package/lib/platform/provider-contract.ts +38 -12
  74. package/lib/platform/provider-validation.ts +83 -12
  75. package/lib/platform/release-notes.ts +11 -12
  76. package/lib/platform/verification-sync.ts +13 -53
  77. package/lib/sandbox/capture.ts +1 -1
  78. package/lib/sandbox/commands/create.ts +52 -1
  79. package/lib/sandbox/commands/enter.ts +1 -1
  80. package/lib/sandbox/commands/start.ts +1 -1
  81. package/lib/sandbox/config.ts +12 -0
  82. package/lib/sandbox/control/client.ts +5 -1
  83. package/lib/sandbox/control/executor.ts +13 -4
  84. package/lib/sandbox/control/lifecycle.ts +22 -13
  85. package/lib/sandbox/control/protocol.ts +3 -2
  86. package/lib/sandbox/removal.ts +23 -7
  87. package/lib/sandbox/task-resolver.ts +51 -2
  88. package/lib/task/activity-intent.ts +1 -2
  89. package/lib/task/artifact-operations.ts +58 -2
  90. package/lib/task/artifact-schema.ts +9 -7
  91. package/lib/task/control-authority.ts +14 -188
  92. package/lib/task/decision-intents.ts +2 -4
  93. package/lib/task/events.ts +8 -27
  94. package/lib/task/finalization-handoff.ts +104 -0
  95. package/lib/task/finalization.ts +120 -12
  96. package/lib/task/intermediate-cleanup.ts +9 -125
  97. package/lib/task/ledger-intents.ts +3 -6
  98. package/lib/task/lifecycle.ts +45 -13
  99. package/lib/task/local-artifact-finalization.ts +16 -35
  100. package/lib/task/resolve-ref.ts +3 -3
  101. package/lib/task/review-command.ts +2 -5
  102. package/lib/task/review-finalization.ts +1 -4
  103. package/lib/task/snapshot.ts +6 -6
  104. package/lib/task/verification-engine.ts +20 -10
  105. package/lib/task/verification.ts +1 -15
  106. package/lib/task/workflow-warning-intents.ts +2 -4
  107. package/lib/task/write.ts +116 -5
  108. package/package.json +1 -1
  109. package/templates/.agents/rules/evidence-reporting.en.md +1 -2
  110. package/templates/.agents/rules/evidence-reporting.zh-CN.md +1 -2
  111. package/templates/.agents/skills/analyze-task/SKILL.en.md +11 -2
  112. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +11 -2
  113. package/templates/.agents/skills/archive-tasks/SKILL.en.md +2 -2
  114. package/templates/.agents/skills/archive-tasks/SKILL.zh-CN.md +2 -2
  115. package/templates/.agents/skills/archive-tasks/scripts/archive-tasks.sh +109 -6
  116. package/templates/.agents/skills/code-task/reference/report-template.en.md +6 -6
  117. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +6 -6
  118. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +2 -2
  119. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +2 -2
  120. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +1 -3
  121. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +1 -3
  122. package/templates/.agents/skills/complete-task/config/verify.en.json +2 -2
  123. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +2 -2
  124. package/templates/.agents/skills/create-release-note/SKILL.en.md +17 -11
  125. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +17 -11
  126. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +3 -3
  127. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +3 -3
  128. package/templates/.agents/skills/review-code/reference/report-template.en.md +3 -3
  129. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +3 -3
  130. package/templates/.agents/skills/review-plan/reference/report-template.en.md +3 -3
  131. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +3 -3
  132. package/templates/.agents/skills/review-pr/config/verify.en.json +3 -1
  133. package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +3 -1
  134. package/templates/.agents/skills/review-pr/reference/report-template.en.md +3 -3
  135. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +3 -3
  136. package/templates/.agents/skills/run-manual-validation/config/verify.en.json +2 -2
  137. package/templates/.agents/skills/run-manual-validation/config/verify.zh-CN.json +2 -2
  138. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +2 -2
  139. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +2 -2
  140. package/dist/lib/internal/task-override.js +0 -138
  141. package/dist/lib/task/artifact-recovery.js +0 -476
  142. package/dist/lib/task/artifact-repair-intent.js +0 -181
  143. package/dist/lib/task/guard-override.js +0 -31
  144. package/dist/lib/task/human-override.js +0 -1259
  145. package/lib/internal/task-override.ts +0 -144
  146. package/lib/task/artifact-recovery.ts +0 -572
  147. package/lib/task/artifact-repair-intent.ts +0 -227
  148. package/lib/task/guard-override.ts +0 -50
  149. package/lib/task/human-override.ts +0 -1522
@@ -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'
@@ -1,11 +1,10 @@
1
1
  import { parseReviewCommand } from '../task/review-command.ts';
2
2
  import { finalizeReviewSummary, preflightReviewSummary } from '../task/review-finalization.ts';
3
- import { consumeHumanOverride, failureId, overrideDryRunConflict } from '../task/human-override.ts';
4
3
  import { resolveTaskRef } from '../task/resolve-ref.ts';
5
4
  import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
6
5
  import { ensureInternalHandlerRoute } from './cli-route-inventory.ts';
7
6
 
8
- const USAGE = 'Usage: agent-infra-internal task-review <task-ref> <preflight|finalize-summary> --stage <analysis|plan|code> --artifact <review-*.md> [--orchestrated] [--dry-run] [--override-ticket <ticket> --override-target <target> --override-scope <scope>]\n';
7
+ const USAGE = 'Usage: agent-infra-internal task-review <task-ref> <preflight|finalize-summary> --stage <analysis|plan|code> --artifact <review-*.md> [--orchestrated] [--dry-run]\n';
9
8
 
10
9
  function failUsage(message: string): void {
11
10
  process.stdout.write(`${JSON.stringify({
@@ -27,37 +26,16 @@ async function taskReview(args: string[] = []): Promise<void> {
27
26
  let request;
28
27
  try { request = parseReviewCommand(args); }
29
28
  catch (error) { failUsage(error instanceof Error ? error.message : String(error)); return; }
30
- const { stage, artifact, dryRun, orchestrated, overrideTicket, overrideTarget, overrideScope } = request;
29
+ const { stage, artifact, dryRun, orchestrated } = request;
31
30
  const operation = args[1]!;
32
- const dryRunConflict = overrideDryRunConflict({ dryRun, overrideTicket, overrideTarget, overrideScope });
33
- if (dryRunConflict) { failUsage(dryRunConflict.message); return; }
34
31
  const resolved = resolveTaskRef(args[0]!);
35
32
  if (!resolved.ok) { failUsage(resolved.message); return; }
36
33
  let result;
37
- let humanOverride: unknown = null;
38
34
  try {
39
35
  result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-review.${operation}`, async () => {
40
- let current = operation === 'preflight'
36
+ return operation === 'preflight'
41
37
  ? preflightReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true })
42
38
  : finalizeReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true });
43
- if (operation === 'preflight') return current;
44
- if (current.status !== 'failed' || !overrideTicket) return current;
45
- if (!overrideTarget || !overrideScope) { failUsage('override ticket requires target and scope'); return current; }
46
- const consumed = await consumeHumanOverride({
47
- taskRef: args[0]!, ticketId: overrideTicket,
48
- failureId: failureId('review-finalization', current.error?.code ?? 'TASK_STATE_MISMATCH'),
49
- target: overrideTarget, scope: overrideScope
50
- }, {
51
- effectExecutor: (capability) => {
52
- const retried = finalizeReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true, manualOverride: capability });
53
- current = retried;
54
- return retried.status === 'failed' || retried.status === 'planned'
55
- ? { code: 'OVERRIDE_EFFECT_FAILED', message: retried.status === 'planned' ? 'producer returned planned; no review effect was committed' : `${retried.error?.code ?? 'REVIEW_FAILED'}: ${retried.error?.message ?? 'manual review effect failed'}` }
56
- : null;
57
- }
58
- });
59
- humanOverride = consumed;
60
- return current;
61
39
  });
62
40
  } catch (error) {
63
41
  if (!(error instanceof TaskExecutionLockError)) throw error;
@@ -65,12 +43,8 @@ async function taskReview(args: string[] = []): Promise<void> {
65
43
  process.exitCode = 1;
66
44
  return;
67
45
  }
68
- process.stdout.write(`${JSON.stringify(humanOverride ? { ...result, humanOverride } : result)}\n`);
69
- const overrideFailed = Boolean(
70
- humanOverride && typeof humanOverride === 'object' &&
71
- (humanOverride as { status?: unknown }).status === 'failed'
72
- );
73
- if (result.status === 'failed' || overrideFailed) process.exitCode = 1;
46
+ process.stdout.write(`${JSON.stringify(result)}\n`);
47
+ if (result.status === 'failed') process.exitCode = 1;
74
48
  }
75
49
 
76
50
  export { taskReview };
@@ -1,10 +1,9 @@
1
1
  import { renderTaskVerification, verifyTaskEvent } from '../task/verification.ts';
2
- import { consumeHumanOverride, failureId } from '../task/human-override.ts';
3
2
  import { resolveTaskRef } from '../task/resolve-ref.ts';
4
3
  import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
5
4
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
6
5
 
7
- const USAGE = 'Usage: agent-infra-internal task-verify <N | TASK-id> <verification-event> [--artifact <canonical.md>] [--format json|text] [--override-ticket <ticket> --override-target <target> --override-scope <scope>]\n';
6
+ const USAGE = 'Usage: agent-infra-internal task-verify <N | TASK-id> <verification-event> [--artifact <canonical.md>] [--format json|text]\n';
8
7
 
9
8
  function fail(message: string): void {
10
9
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'VERIFY_PAYLOAD_INVALID', message } })}\n`);
@@ -21,63 +20,28 @@ async function taskVerify(args: string[] = []): Promise<void> {
21
20
  const event = args[1];
22
21
  let artifact: string | undefined;
23
22
  let format: 'json' | 'text' = 'json';
24
- let overrideTicket: string | undefined;
25
- let overrideTarget: string | undefined;
26
- let overrideScope: string | undefined;
27
23
  const seen = new Set<string>();
28
24
  for (let index = 2; index < args.length; index += 1) {
29
25
  const flag = args[index]!;
30
- if (!['--artifact', '--format', '--override-ticket', '--override-target', '--override-scope'].includes(flag)) { fail(`unknown option '${flag}'`); return; }
26
+ if (!['--artifact', '--format'].includes(flag)) { fail(`unknown option '${flag}'`); return; }
31
27
  if (seen.has(flag)) { fail(`duplicate option '${flag}'`); return; }
32
28
  const value = args[++index];
33
29
  if (!value || value.startsWith('--')) { fail(`option '${flag}' requires a value`); return; }
34
30
  seen.add(flag);
35
31
  if (flag === '--artifact') artifact = value;
36
- else if (flag === '--override-ticket') overrideTicket = value;
37
- else if (flag === '--override-target') overrideTarget = value;
38
- else if (flag === '--override-scope') overrideScope = value;
39
32
  else if (value === 'json' || value === 'text') format = value;
40
33
  else { fail("option '--format' requires 'json' or 'text'"); return; }
41
34
  }
42
35
  const resolved = resolveTaskRef(taskRef);
43
36
  if (!resolved.ok) { fail(resolved.message); return; }
44
37
  let result;
45
- let humanOverride: unknown = null;
46
38
  try {
47
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-verify.${event}`, async () => {
48
- let current = await verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) });
49
- if (current.status === 'pass' || !overrideTicket) return current;
50
- if (!overrideTarget || !overrideScope) { fail('override ticket requires target and scope'); return current; }
51
- const failureProducer = current.status === 'blocked' || current.status === 'fail'
52
- ? 'verification-engine'
53
- : 'task-verify';
54
- const failureCode = current.status === 'blocked'
55
- ? 'CHECK_BLOCKED'
56
- : current.status === 'fail'
57
- ? 'CHECK_FAILED'
58
- : current.error?.code ?? 'VERIFY_TASK_STATE_MISMATCH';
59
- const consumed = await consumeHumanOverride({
60
- taskRef, ticketId: overrideTicket,
61
- failureId: failureId(failureProducer, failureCode),
62
- target: overrideTarget, scope: overrideScope
63
- }, {
64
- effectExecutor: async (capability) => {
65
- const retried = await verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) }, { manualOverride: capability });
66
- current = retried;
67
- return retried.status !== 'pass'
68
- ? { code: 'OVERRIDE_EFFECT_FAILED', message: `${retried.error?.code ?? 'VERIFY_FAILED'}: ${retried.error?.message ?? 'manual verification effect failed'}` }
69
- : null;
70
- }
71
- });
72
- humanOverride = consumed;
73
- return current;
74
- });
39
+ result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-verify.${event}`, async () => verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) }));
75
40
  } catch (error) {
76
41
  if (!(error instanceof TaskExecutionLockError)) throw error;
77
42
  fail(`${error.code}: ${error.message}`);
78
43
  return;
79
44
  }
80
- if (humanOverride) result = { ...result, humanOverride } as typeof result;
81
45
  process.stdout.write(format === 'text' ? renderTaskVerification(result) : `${JSON.stringify(result)}\n`);
82
46
  process.exitCode = result.status === 'pass' ? 0 : result.status === 'blocked' ? 2 : 1;
83
47
  }
@@ -1,6 +1,5 @@
1
1
  import { applyWorkflowWarningIntent } from '../task/workflow-warning-intents.ts';
2
2
  import type { WorkflowWarningIntent } from '../task/workflow-warning-intents.ts';
3
- import { consumeHumanOverride, failureId, overrideDryRunConflict } from '../task/human-override.ts';
4
3
  import { resolveTaskRef } from '../task/resolve-ref.ts';
5
4
  import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
6
5
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
@@ -9,7 +8,6 @@ const USAGE = `Usage: agent-infra-internal task-warning <task-ref> <add|set-stat
9
8
  const FLAGS: Record<string, string> = {
10
9
  '--step': 'step', '--severity': 'severity', '--code': 'code', '--target': 'target',
11
10
  '--message': 'message', '--action': 'action', '--id': 'id', '--status': 'status', '--resolution': 'resolution'
12
- , '--override-ticket': 'overrideTicket', '--override-target': 'overrideTarget', '--override-scope': 'overrideScope'
13
11
  };
14
12
 
15
13
  function usageFailure(message: string): void {
@@ -48,50 +46,23 @@ async function taskWarning(args: string[] = []): Promise<void> {
48
46
  };
49
47
  const optional = kind === 'list' ? ['status'] : [];
50
48
  const allowed = new Set(['kind', 'taskRef', 'dryRun', ...required[kind]!, ...optional]);
51
- allowed.add('overrideTicket'); allowed.add('overrideTarget'); allowed.add('overrideScope');
52
49
  const unexpected = Object.keys(values).find((key) => !allowed.has(key));
53
50
  const missing = required[kind]!.find((key) => values[key] === undefined);
54
51
  if (unexpected) { usageFailure(`${kind} does not accept '${unexpected}'`); return; }
55
52
  if (missing) { usageFailure(`${kind} requires '${missing}'`); return; }
56
- const dryRunConflict = overrideDryRunConflict(values);
57
- if (dryRunConflict) { usageFailure(dryRunConflict.message); return; }
58
53
  const resolved = resolveTaskRef(taskRef);
59
54
  if (!resolved.ok) { usageFailure(resolved.message); return; }
60
55
  let result;
61
- let humanOverride: unknown = null;
62
56
  try {
63
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-warning.${kind}`, async () => {
64
- let current = applyWorkflowWarningIntent(values as WorkflowWarningIntent);
65
- if (current.status !== 'failed' || !values.overrideTicket) return current;
66
- if (!values.overrideTarget || !values.overrideScope) { usageFailure('override ticket requires target and scope'); return current; }
67
- const consumed = await consumeHumanOverride({
68
- taskRef, ticketId: String(values.overrideTicket),
69
- failureId: failureId('workflow-warning', current.error?.code ?? 'TASK_STATE_MISMATCH'),
70
- target: String(values.overrideTarget), scope: String(values.overrideScope)
71
- }, {
72
- effectExecutor: (capability) => {
73
- const retried = applyWorkflowWarningIntent(values as WorkflowWarningIntent, { manualOverride: capability });
74
- current = retried;
75
- return retried.status === 'failed' || retried.status === 'planned'
76
- ? { code: 'OVERRIDE_EFFECT_FAILED', message: retried.status === 'planned' ? 'producer returned planned; no workflow warning effect was committed' : `${retried.error?.code ?? 'WARNING_FAILED'}: ${retried.error?.message ?? 'manual warning effect failed'}` }
77
- : null;
78
- }
79
- });
80
- humanOverride = consumed;
81
- return current;
82
- });
57
+ result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-warning.${kind}`, async () => applyWorkflowWarningIntent(values as WorkflowWarningIntent));
83
58
  } catch (error) {
84
59
  if (!(error instanceof TaskExecutionLockError)) throw error;
85
60
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
86
61
  process.exitCode = 1;
87
62
  return;
88
63
  }
89
- process.stdout.write(`${JSON.stringify(humanOverride ? { ...result, humanOverride } : result)}\n`);
90
- const overrideFailed = Boolean(
91
- humanOverride && typeof humanOverride === 'object' &&
92
- (humanOverride as { status?: unknown }).status === 'failed'
93
- );
94
- if (result.status === 'failed' || overrideFailed) process.exitCode = 1;
64
+ process.stdout.write(`${JSON.stringify(result)}\n`);
65
+ if (result.status === 'failed') process.exitCode = 1;
95
66
  }
96
67
 
97
68
  export { taskWarning };