@fitlab-ai/agent-infra 0.12.1 → 0.12.2
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.
- package/README.md +0 -2
- package/README.zh-CN.md +0 -2
- package/dist/bin/internal-cli.js +2 -17
- package/dist/lib/agent-clients/adapter.js +0 -13
- package/dist/lib/agent-clients/adapters/antigravity-cli.js +0 -5
- package/dist/lib/agent-clients/adapters/claude-code-credentials.js +0 -17
- package/dist/lib/agent-clients/adapters/claude-code.js +0 -9
- package/dist/lib/agent-clients/adapters/codex.js +0 -52
- package/dist/lib/agent-clients/adapters/opencode.js +0 -5
- package/dist/lib/agent-clients/adapters/traecli.js +0 -5
- package/dist/lib/agent-clients/config.js +19 -54
- package/dist/lib/agent-clients/registry.js +1 -12
- package/dist/lib/agent-clients/schema.js +0 -18
- package/dist/lib/agent-clients/tokens.js +1 -2
- package/dist/lib/agent-clients/types.js +0 -1
- package/dist/lib/decide.js +2 -0
- package/dist/lib/git/worktree-identity.js +1 -9
- package/dist/lib/internal/agent-client.js +2 -62
- package/dist/lib/internal/cli-route-inventory.js +1 -5
- package/dist/lib/internal/manual-validation.js +18 -10
- package/dist/lib/internal/task-create.js +1 -1
- package/dist/lib/internal/task-event.js +1 -8
- package/dist/lib/internal/task-finalization.js +0 -1
- package/dist/lib/internal/task-lifecycle.js +2 -2
- package/dist/lib/internal/task-operation-registry.js +4 -20
- package/dist/lib/internal/task-review.js +4 -4
- package/dist/lib/platform/comment-safety.js +1 -7
- package/dist/lib/platform/in-label-sync.js +1 -14
- package/dist/lib/platform/issue-comments.js +1 -16
- package/dist/lib/platform/issues.js +1 -1
- package/dist/lib/platform/operation-coordinator.js +4 -2
- package/dist/lib/platform/pr-change-report.js +1 -4
- package/dist/lib/platform/pr-checks.js +2 -8
- package/dist/lib/platform/provider-validation.js +0 -20
- package/dist/lib/platform/pull-requests.js +73 -84
- package/dist/lib/platform/releases.js +1 -43
- package/dist/lib/platform/verification-required.js +0 -2
- package/dist/lib/platform/verification-sync.js +1 -79
- package/dist/lib/process-data/normalize.js +1 -185
- package/dist/lib/process-data/privacy.js +1 -16
- package/dist/lib/process-data/sources.js +2 -279
- package/dist/lib/render.js +0 -12
- package/dist/lib/run/index.js +15 -10
- package/dist/lib/run/skills.js +0 -3
- package/dist/lib/sandbox/commands/create.js +40 -53
- package/dist/lib/sandbox/commands/list-running.js +0 -18
- package/dist/lib/sandbox/commands/start.js +7 -8
- package/dist/lib/sandbox/constants.js +0 -6
- package/dist/lib/sandbox/control/client.js +0 -1
- package/dist/lib/sandbox/control/container-identity.js +1 -16
- package/dist/lib/sandbox/control/executor.js +0 -4
- package/dist/lib/sandbox/control/identity-sentinel.js +0 -7
- package/dist/lib/sandbox/control/lifecycle.js +21 -37
- package/dist/lib/sandbox/control/native-file-lock.js +0 -3
- package/dist/lib/sandbox/control/server.js +18 -38
- package/dist/lib/sandbox/control/state.js +1 -9
- package/dist/lib/sandbox/dockerfile.js +0 -6
- package/dist/lib/sandbox/engine.js +0 -14
- package/dist/lib/sandbox/engines/docker-exact-discovery.js +1 -4
- package/dist/lib/sandbox/engines/wsl2-paths.js +0 -3
- package/dist/lib/sandbox/recovery.js +24 -26
- package/dist/lib/sandbox/removal.js +11 -519
- package/dist/lib/sandbox/task-resolver.js +0 -41
- package/dist/lib/sandbox/tools.js +1 -4
- package/dist/lib/sandbox/workspace-view.js +1 -2
- package/dist/lib/server/display.js +0 -6
- package/dist/lib/task/activity-intent.js +45 -40
- package/dist/lib/task/activity-log.js +9 -16
- package/dist/lib/task/artifact-command.js +1 -1
- package/dist/lib/task/artifact-lifecycle.js +61 -63
- package/dist/lib/task/artifact-name.js +0 -6
- package/dist/lib/task/artifact-operations.js +3 -3
- package/dist/lib/task/capabilities.js +4 -5
- package/dist/lib/task/commands/log.js +0 -6
- package/dist/lib/task/commands/status.js +17 -60
- package/dist/lib/task/commit-operation.js +28 -39
- package/dist/lib/task/completion-facts.js +56 -43
- package/dist/lib/task/control-authority.js +23 -256
- package/dist/lib/task/control-recovery.js +3 -5
- package/dist/lib/task/create.js +2 -4
- package/dist/lib/task/decision-intents.js +8 -9
- package/dist/lib/task/delivery-target.js +1 -40
- package/dist/lib/task/events.js +84 -107
- package/dist/lib/task/finalization.js +44 -8
- package/dist/lib/task/ledger-intents.js +1 -1
- package/dist/lib/task/lifecycle-execution.js +38 -33
- package/dist/lib/task/lifecycle.js +49 -41
- package/dist/lib/task/local-artifact-finalization.js +1 -4
- package/dist/lib/task/manual-validation-evidence.js +1 -37
- package/dist/lib/task/platform-operation-recovery.js +67 -24
- package/dist/lib/task/pr-delivery-fact.js +2 -5
- package/dist/lib/task/qualification-confirmation.js +5 -7
- package/dist/lib/task/resolve-ref.js +1 -25
- package/dist/lib/task/review-command.js +2 -2
- package/dist/lib/task/review-finalization.js +1 -21
- package/dist/lib/task/review-fingerprint.js +0 -4
- package/dist/lib/task/secure-fs.js +0 -56
- package/dist/lib/task/short-id.js +1 -39
- package/dist/lib/task/skill-scope.js +0 -1
- package/dist/lib/task/verification-engine.js +58 -282
- package/dist/lib/task/verification.js +6 -3
- package/dist/lib/task/write.js +11 -1
- package/lib/agent-clients/adapter.ts +0 -76
- package/lib/agent-clients/adapters/antigravity-cli.ts +0 -5
- package/lib/agent-clients/adapters/claude-code-credentials.ts +0 -19
- package/lib/agent-clients/adapters/claude-code.ts +0 -9
- package/lib/agent-clients/adapters/codex.ts +0 -56
- package/lib/agent-clients/adapters/opencode.ts +0 -5
- package/lib/agent-clients/adapters/traecli.ts +0 -5
- package/lib/agent-clients/config.ts +20 -61
- package/lib/agent-clients/registry.ts +1 -34
- package/lib/agent-clients/schema.ts +0 -18
- package/lib/agent-clients/tokens.ts +1 -2
- package/lib/agent-clients/types.ts +0 -15
- package/lib/decide.ts +1 -0
- package/lib/git/worktree-identity.ts +0 -10
- package/lib/internal/agent-client.ts +2 -70
- package/lib/internal/cli-route-inventory.ts +1 -4
- package/lib/internal/manual-validation.ts +16 -9
- package/lib/internal/task-create.ts +0 -1
- package/lib/internal/task-event.ts +1 -5
- package/lib/internal/task-finalization.ts +0 -1
- package/lib/internal/task-lifecycle.ts +3 -5
- package/lib/internal/task-operation-registry.ts +3 -19
- package/lib/internal/task-review.ts +4 -4
- package/lib/platform/comment-safety.ts +0 -10
- package/lib/platform/github-provider.ts +0 -2
- package/lib/platform/in-label-sync.ts +0 -16
- package/lib/platform/issue-comments.ts +0 -21
- package/lib/platform/issues.ts +0 -2
- package/lib/platform/operation-coordinator.ts +4 -2
- package/lib/platform/pr-change-report.ts +0 -5
- package/lib/platform/pr-checks.ts +1 -10
- package/lib/platform/pr-review.ts +1 -1
- package/lib/platform/provider-bridge.ts +0 -1
- package/lib/platform/provider-loader.ts +1 -5
- package/lib/platform/provider-validation.ts +1 -49
- package/lib/platform/pull-requests.ts +64 -99
- package/lib/platform/releases.ts +1 -40
- package/lib/platform/verification-required.ts +0 -2
- package/lib/platform/verification-sync.ts +0 -94
- package/lib/process-data/normalize.ts +1 -186
- package/lib/process-data/privacy.ts +2 -19
- package/lib/process-data/sources.ts +3 -283
- package/lib/render.ts +0 -15
- package/lib/run/index.ts +13 -7
- package/lib/run/skills.ts +0 -4
- package/lib/sandbox/commands/create.ts +37 -74
- package/lib/sandbox/commands/list-running.ts +0 -19
- package/lib/sandbox/commands/start.ts +7 -10
- package/lib/sandbox/constants.ts +0 -8
- package/lib/sandbox/control/client.ts +0 -1
- package/lib/sandbox/control/container-identity.ts +1 -16
- package/lib/sandbox/control/executor.ts +1 -5
- package/lib/sandbox/control/identity-sentinel.ts +0 -8
- package/lib/sandbox/control/lifecycle.ts +18 -51
- package/lib/sandbox/control/native-file-lock.ts +0 -8
- package/lib/sandbox/control/protocol.ts +0 -2
- package/lib/sandbox/control/server.ts +13 -39
- package/lib/sandbox/control/state.ts +1 -10
- package/lib/sandbox/dockerfile.ts +0 -11
- package/lib/sandbox/engine.ts +0 -17
- package/lib/sandbox/engines/docker-exact-discovery.ts +1 -5
- package/lib/sandbox/engines/wsl2-paths.ts +0 -4
- package/lib/sandbox/recovery.ts +24 -26
- package/lib/sandbox/removal.ts +11 -696
- package/lib/sandbox/shell.ts +1 -1
- package/lib/sandbox/task-resolver.ts +0 -48
- package/lib/sandbox/tools.ts +1 -5
- package/lib/sandbox/workspace-view.ts +2 -4
- package/lib/server/display.ts +0 -14
- package/lib/server/process-control.ts +1 -1
- package/lib/task/activity-intent.ts +36 -44
- package/lib/task/activity-log.ts +9 -22
- package/lib/task/artifact-command.ts +1 -1
- package/lib/task/artifact-lifecycle.ts +58 -67
- package/lib/task/artifact-name.ts +0 -7
- package/lib/task/artifact-operations.ts +3 -3
- package/lib/task/capabilities.ts +5 -6
- package/lib/task/commands/log.ts +0 -7
- package/lib/task/commands/status.ts +14 -79
- package/lib/task/commit-operation.ts +29 -51
- package/lib/task/completion-facts.ts +45 -42
- package/lib/task/control-authority.ts +27 -317
- package/lib/task/control-recovery.ts +2 -5
- package/lib/task/create.ts +2 -5
- package/lib/task/decision-intents.ts +5 -5
- package/lib/task/delivery-target.ts +0 -40
- package/lib/task/events.ts +89 -123
- package/lib/task/finalization.ts +41 -9
- package/lib/task/ledger-intents.ts +1 -1
- package/lib/task/lifecycle-execution.ts +37 -89
- package/lib/task/lifecycle.ts +48 -44
- package/lib/task/local-artifact-finalization.ts +0 -7
- package/lib/task/manual-validation-evidence.ts +1 -47
- package/lib/task/platform-operation-recovery.ts +50 -26
- package/lib/task/pr-delivery-fact.ts +2 -11
- package/lib/task/qualification-confirmation.ts +6 -6
- package/lib/task/resolve-ref.ts +0 -23
- package/lib/task/review-command.ts +2 -2
- package/lib/task/review-finalization.ts +1 -27
- package/lib/task/review-fingerprint.ts +0 -8
- package/lib/task/secure-fs.ts +0 -42
- package/lib/task/short-id.ts +0 -43
- package/lib/task/skill-scope.ts +0 -1
- package/lib/task/verification-engine.ts +56 -287
- package/lib/task/verification.ts +5 -5
- package/lib/task/write.ts +12 -1
- package/package.json +2 -2
- package/templates/.agents/README.en.md +1 -3
- package/templates/.agents/README.zh-CN.md +0 -2
- package/templates/.agents/rules/README.en.md +0 -1
- package/templates/.agents/rules/README.zh-CN.md +0 -1
- package/templates/.agents/rules/commit-and-pr.en.md +1 -1
- package/templates/.agents/rules/commit-and-pr.zh-CN.md +1 -1
- package/templates/.agents/rules/no-mid-flow-questions.en.md +0 -10
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +0 -10
- package/templates/.agents/rules/pr-sync.en.md +1 -1
- package/templates/.agents/rules/pr-sync.zh-CN.md +1 -1
- package/templates/.agents/rules/task-management.en.md +3 -3
- package/templates/.agents/rules/task-management.zh-CN.md +3 -3
- package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -3
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/code-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/commit/SKILL.en.md +2 -2
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +6 -6
- package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +6 -6
- package/templates/.agents/skills/plan-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-analysis/SKILL.en.md +3 -3
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/review-code/SKILL.en.md +5 -5
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/review-plan/SKILL.en.md +3 -3
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/review-pr/SKILL.en.md +4 -4
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +3 -75
- package/templates/.agents/templates/task.en.md +1 -0
- package/templates/.agents/templates/task.zh-CN.md +1 -0
- package/templates/.claude/settings.json +0 -24
- package/templates/.codex/hooks.json +0 -50
- package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +0 -582
- package/dist/lib/agent-clients/adapters/codex-lifecycle/binding.js +0 -114
- package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +0 -237
- package/dist/lib/agent-clients/adapters/codex-lifecycle/cli.js +0 -443
- package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +0 -236
- package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +0 -292
- package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +0 -267
- package/dist/lib/agent-clients/adapters/codex-orchestration.js +0 -466
- package/dist/lib/internal/task-orchestration.js +0 -71
- package/dist/lib/platform/verification.js +0 -6
- package/dist/lib/run/prompt.js +0 -2
- package/dist/lib/sandbox/engines/authority.js +0 -289
- package/dist/lib/task/delegation-receipts.js +0 -410
- package/dist/lib/task/orchestration.js +0 -1233
- package/dist/lib/task/verification-checks.js +0 -9
- package/dist/lib/task/workspace-snapshot.js +0 -121
- package/dist/lifecycle-build-manifest.json +0 -6
- package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +0 -688
- package/lib/agent-clients/adapters/codex-lifecycle/binding.ts +0 -147
- package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +0 -349
- package/lib/agent-clients/adapters/codex-lifecycle/cli.ts +0 -506
- package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +0 -385
- package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +0 -41
- package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +0 -418
- package/lib/agent-clients/adapters/codex-lifecycle/store.ts +0 -354
- package/lib/agent-clients/adapters/codex-orchestration.ts +0 -630
- package/lib/internal/task-orchestration.ts +0 -74
- package/lib/platform/verification.ts +0 -11
- package/lib/run/prompt.ts +0 -1
- package/lib/sandbox/engines/authority.ts +0 -365
- package/lib/task/delegation-receipts.ts +0 -547
- package/lib/task/orchestration.ts +0 -1651
- package/lib/task/verification-checks.ts +0 -10
- package/lib/task/workspace-snapshot.ts +0 -144
- package/templates/.agents/hooks/lifecycle-delegation.js +0 -140
- package/templates/.agents/rules/lifecycle-orchestration.en.md +0 -44
- package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +0 -44
- package/templates/.agents/skills/run-task/SKILL.en.md +0 -29
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +0 -29
- package/templates/.agents/skills/run-task/config/verify.en.json +0 -10
- package/templates/.agents/skills/run-task/config/verify.zh-CN.json +0 -10
- package/templates/.agents/skills/run-task/reference/host-validation.en.md +0 -24
- package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +0 -24
- package/templates/.claude/agents/agent-infra-lifecycle-executor.en.md +0 -6
- package/templates/.claude/agents/agent-infra-lifecycle-executor.zh-CN.md +0 -6
- package/templates/.claude/agents/agent-infra-lifecycle-reviewer.en.md +0 -6
- package/templates/.claude/agents/agent-infra-lifecycle-reviewer.zh-CN.md +0 -6
- package/templates/.claude/commands/run-task.en.md +0 -8
- package/templates/.claude/commands/run-task.zh-CN.md +0 -8
- package/templates/.codex/agents/agent-infra-lifecycle-executor.en.toml +0 -3
- package/templates/.codex/agents/agent-infra-lifecycle-executor.zh-CN.toml +0 -3
- package/templates/.codex/agents/agent-infra-lifecycle-reviewer.en.toml +0 -3
- package/templates/.codex/agents/agent-infra-lifecycle-reviewer.zh-CN.toml +0 -3
- package/templates/.opencode/commands/run-task.en.md +0 -11
- package/templates/.opencode/commands/run-task.zh-CN.md +0 -11
package/dist/lib/task/create.js
CHANGED
|
@@ -8,6 +8,7 @@ import { readDeliveryDefaults, validateBaseRef, validateRemote } from './deliver
|
|
|
8
8
|
import { buildUnboundFact, encodePrDeliveryFact } from './pr-delivery-fact.js';
|
|
9
9
|
import { CANDIDATE_COLUMNS, CONSTRAINT_COLUMNS, parseTaskQualification } from './qualification-audit.js';
|
|
10
10
|
import { enumerateAllTaskDirs } from './resolve-ref.js';
|
|
11
|
+
import { serializeLifecycleExecution } from './lifecycle-execution.js';
|
|
11
12
|
import { parseTaskFrontmatter } from './frontmatter.js';
|
|
12
13
|
import { AGENT_TOKEN_VALUES } from '../agent-clients/tokens.js';
|
|
13
14
|
import { resolveProjectTaskWorkspaceRoot } from './workspace-root.js';
|
|
@@ -23,7 +24,6 @@ function payloadError(message) {
|
|
|
23
24
|
}
|
|
24
25
|
function exactKeys(value, expected, label, optional = []) {
|
|
25
26
|
const actual = Object.keys(value).sort();
|
|
26
|
-
const wanted = [...expected].sort();
|
|
27
27
|
const allowed = new Set([...expected, ...optional]);
|
|
28
28
|
if (actual.some((key) => !allowed.has(key))) {
|
|
29
29
|
payloadError(`${label} has unknown or missing fields`);
|
|
@@ -134,9 +134,6 @@ function taskIdFor(date) {
|
|
|
134
134
|
const pad = (value) => String(value).padStart(2, '0');
|
|
135
135
|
return `TASK-${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}-${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`;
|
|
136
136
|
}
|
|
137
|
-
function yamlString(value) {
|
|
138
|
-
return JSON.stringify(value);
|
|
139
|
-
}
|
|
140
137
|
function markdownBlock(value) {
|
|
141
138
|
return value.split(/\r?\n/).map((line) => /^(?:#{1,6}\s|```)/.test(line) ? `\\${line}` : line).join('\n');
|
|
142
139
|
}
|
|
@@ -237,6 +234,7 @@ function renderTask(params) {
|
|
|
237
234
|
'target_date:',
|
|
238
235
|
'current_step: requirement-analysis',
|
|
239
236
|
`assigned_to: ${candidate.agent}`,
|
|
237
|
+
`lifecycle_execution: ${JSON.stringify(serializeLifecycleExecution([]))}`,
|
|
240
238
|
`pr_delivery_fact: ${JSON.stringify(encodePrDeliveryFact(buildUnboundFact()))}`,
|
|
241
239
|
`delivery_remote: ${candidate.deliveryRemote ?? params.delivery.remote}`,
|
|
242
240
|
`delivery_base_ref: ${candidate.deliveryBaseRef ?? params.delivery.baseRef}`,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { appendActivityEntry, locateActivityLog } from './activity-log.js';
|
|
2
|
+
import { activityWarnings, appendActivityEntry, locateActivityLog } from './activity-log.js';
|
|
3
3
|
import { isDecisionItem, listDecisionItems, selectDecisionItem } from './decision-items.js';
|
|
4
4
|
import { createImplementationInput, finalizeImplementationInput, IMPLEMENTATION_INPUT_ALIASES, parseImplementationInputs, renderImplementationInputs, selectDeclaredImplementationInput } from './implementation-inputs.js';
|
|
5
5
|
import { LEDGER_COLUMNS, LEDGER_HEADINGS, LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, parseLedgerDocument } from './ledger.js';
|
|
@@ -77,7 +77,7 @@ function applyHumanDecision(request, options = {}) {
|
|
|
77
77
|
const replay = existingDecision(content, direct[0], request.decision.trim(), request.needsImplementation);
|
|
78
78
|
if ('conflict' in replay)
|
|
79
79
|
return failed('DECISION_CONFLICT', replay.conflict, resolved.taskId, direct[0].id);
|
|
80
|
-
return { status: 'no-op', changed: false, taskId: resolved.taskId, ledgerId: direct[0].id, recordId: replay.recordId, implementationInputId: replay.implementationInputId, operations: [], error: null };
|
|
80
|
+
return { status: 'no-op', changed: false, taskId: resolved.taskId, ledgerId: direct[0].id, recordId: replay.recordId, implementationInputId: replay.implementationInputId, operations: [], error: null, warnings: activityWarnings(content) };
|
|
81
81
|
}
|
|
82
82
|
catch (error) {
|
|
83
83
|
return failed('DECISION_DOCUMENT_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId, direct[0].id);
|
|
@@ -126,8 +126,6 @@ function applyHumanDecision(request, options = {}) {
|
|
|
126
126
|
const decision = request.decision.trim();
|
|
127
127
|
const record = `### ${recordId}\n\n- **原账本 ID**:${row.id}\n- **裁决时间**:${metadata.timestamp}\n- **裁决结果**:${decision}`;
|
|
128
128
|
const activity = locateActivityLog(content);
|
|
129
|
-
if (!activity)
|
|
130
|
-
return failed('DECISION_ACTIVITY_MISSING', 'activity log section is missing or ambiguous', resolved.taskId, row.id);
|
|
131
129
|
const mutations = [
|
|
132
130
|
{
|
|
133
131
|
kind: 'table-row', action: 'upsert', sectionAliases: LEDGER_HEADINGS, columns: LEDGER_COLUMNS,
|
|
@@ -155,10 +153,11 @@ function applyHumanDecision(request, options = {}) {
|
|
|
155
153
|
body: renderImplementationInputs(nextInputs)
|
|
156
154
|
});
|
|
157
155
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
if (activity)
|
|
157
|
+
mutations.push({
|
|
158
|
+
kind: 'section', aliases: ACTIVITY_ALIASES, heading: activity.heading,
|
|
159
|
+
body: appendActivityEntry(activity, { time: metadata.timestamp, step: 'Human Decision', agent: 'human', note: `${row.id} decided → ${recordId}` })
|
|
160
|
+
});
|
|
162
161
|
try {
|
|
163
162
|
const parsedRework = parseReworkIntentDocument(content);
|
|
164
163
|
if (!parsedRework.ok)
|
|
@@ -177,7 +176,7 @@ function applyHumanDecision(request, options = {}) {
|
|
|
177
176
|
});
|
|
178
177
|
if (writeResult.status === 'failed')
|
|
179
178
|
return failed(writeResult.error.code, writeResult.error.message, writeResult.taskId, row.id);
|
|
180
|
-
return { status: writeResult.status, changed: writeResult.changed, taskId: writeResult.taskId, ledgerId: row.id, recordId, implementationInputId, operations: writeResult.operations, error: null };
|
|
179
|
+
return { status: writeResult.status, changed: writeResult.changed, taskId: writeResult.taskId, ledgerId: row.id, recordId, implementationInputId, operations: writeResult.operations, error: null, warnings: activityWarnings(content) };
|
|
181
180
|
}
|
|
182
181
|
export { applyHumanDecision };
|
|
183
182
|
//# sourceMappingURL=decision-intents.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { execFileSync } from 'node:child_process';
|
|
4
3
|
const REMOTE_RE = /^(?!-)(?!.*\.\.)(?!.*[~^:?*\\\s])[A-Za-z0-9._/-]+$/;
|
|
5
4
|
const REF_RE = /^(?!-)(?!.*\.\.)(?!.*(?:^|\/)\.)(?!.*[~^:?*\\\s])[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)*$/;
|
|
6
5
|
function validateRemote(value) {
|
|
@@ -55,43 +54,5 @@ function resolveDeliveryTarget(repoRoot, existing = {}, explicit = {}) {
|
|
|
55
54
|
return defaults;
|
|
56
55
|
return bindDeliveryTarget({ defaults: defaults.value, existing, explicit });
|
|
57
56
|
}
|
|
58
|
-
|
|
59
|
-
return execFileSync('git', [...args], {
|
|
60
|
-
cwd: repoRoot,
|
|
61
|
-
encoding: 'utf8',
|
|
62
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
63
|
-
}).trim();
|
|
64
|
-
}
|
|
65
|
-
function resolveTargetHead(repoRoot, target) {
|
|
66
|
-
try {
|
|
67
|
-
const output = gitText(repoRoot, ['ls-remote', '--refs', target.remote, `refs/heads/${target.baseRef}`]);
|
|
68
|
-
const head = output.split(/\s+/)[0] ?? '';
|
|
69
|
-
if (!/^[a-f0-9]{40}$/i.test(head)) {
|
|
70
|
-
return { ok: false, code: 'DELIVERY_TARGET_UNAVAILABLE', message: `Delivery target ${target.remote}/${target.baseRef} is unavailable` };
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
gitText(repoRoot, ['cat-file', '-e', `${head}^{commit}`]);
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
return { ok: false, code: 'DELIVERY_TARGET_OBJECT_MISSING', message: `Delivery target commit ${head} is not available locally` };
|
|
77
|
-
}
|
|
78
|
-
return { ok: true, value: target, head };
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
return { ok: false, code: 'DELIVERY_TARGET_UNAVAILABLE', message: error instanceof Error ? error.message : String(error) };
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
function resolveDiffBase(repoRoot, reviewedHead, targetHead) {
|
|
85
|
-
try {
|
|
86
|
-
const diffBase = gitText(repoRoot, ['merge-base', reviewedHead, targetHead]);
|
|
87
|
-
if (!/^[a-f0-9]{40}$/i.test(diffBase)) {
|
|
88
|
-
return { ok: false, code: 'DELIVERY_DIFF_BASE_UNAVAILABLE', message: 'Git returned an invalid diff base' };
|
|
89
|
-
}
|
|
90
|
-
return { ok: true, diffBase };
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
return { ok: false, code: 'DELIVERY_DIFF_BASE_UNAVAILABLE', message: error instanceof Error ? error.message : String(error) };
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
export { bindDeliveryTarget, readDeliveryDefaults, resolveDeliveryTarget, resolveTargetHead, resolveDiffBase, validateBaseRef, validateRemote };
|
|
57
|
+
export { bindDeliveryTarget, readDeliveryDefaults, resolveDeliveryTarget, validateBaseRef, validateRemote };
|
|
97
58
|
//# sourceMappingURL=delivery-target.js.map
|
package/dist/lib/task/events.js
CHANGED
|
@@ -2,7 +2,8 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { execFileSync } from 'node:child_process';
|
|
4
4
|
import { resolveBranchWorktree } from '../git/branch-worktree.js';
|
|
5
|
-
import { appendActivityEntry,
|
|
5
|
+
import { appendActivityEntry, inspectActivityLog } from './activity-log.js';
|
|
6
|
+
import { lifecycleExecutions, serializeLifecycleExecution } from './lifecycle-execution.js';
|
|
6
7
|
import { buildArtifactLinkSection, inspectArtifactDirectory, resolveArtifactContext, validateCompletedArtifact } from './artifact-lifecycle.js';
|
|
7
8
|
import { artifactName, parseArtifactName } from './artifact-name.js';
|
|
8
9
|
import { ArtifactReceiptError, parseArtifactReceipts, sha256File, upsertArtifactReceipts } from './artifact-receipts.js';
|
|
@@ -13,8 +14,6 @@ import { parseReviewSummary, resolveCanonicalVerdict } from './review-artifacts.
|
|
|
13
14
|
import { extractReviewBaseline, extractReviewedHead, extractReviewedSnapshotTree } from './review-fingerprint.js';
|
|
14
15
|
import { resolveTaskRef } from './resolve-ref.js';
|
|
15
16
|
import { findSectionHeading } from './sections.js';
|
|
16
|
-
import { validateLifecycleExecution } from './lifecycle-execution.js';
|
|
17
|
-
import { commitOrchestrationStageCompletion } from './orchestration.js';
|
|
18
17
|
import { captureTaskWriteMetadata, writeTask } from './write.js';
|
|
19
18
|
import { validateLocalArtifact } from './local-artifact-finalization.js';
|
|
20
19
|
import { buildLifecycleFacts, canStart, effectiveReworkTarget } from './capabilities.js';
|
|
@@ -23,7 +22,7 @@ import { parseTaskQualification } from './qualification-audit.js';
|
|
|
23
22
|
import { getArtifactSchema } from './artifact-schema.js';
|
|
24
23
|
import { canonicalSemanticDigest, inspectArtifactContract } from './artifact-operations.js';
|
|
25
24
|
import { inspectReviewIdentity } from './review-identity.js';
|
|
26
|
-
import { parseCompletionFacts } from './completion-facts.js';
|
|
25
|
+
import { hasValidArtifactCompletion, parseCompletionFacts } from './completion-facts.js';
|
|
27
26
|
import { readManualValidationCompletion } from './manual-validation-completion.js';
|
|
28
27
|
import { parseLifecyclePathDecision } from './lifecycle-path.js';
|
|
29
28
|
const eventCatalog = [
|
|
@@ -69,17 +68,17 @@ const BASE_FIELDS = new Set(['taskRef', 'event', 'agent', 'dryRun', 'initiator',
|
|
|
69
68
|
const SCHEMAS = {
|
|
70
69
|
'analyze.started': { optional: ['round'] },
|
|
71
70
|
'analyze.awaiting-input': { required: ['question'] },
|
|
72
|
-
'analyze.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round'
|
|
71
|
+
'analyze.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round'] },
|
|
73
72
|
'review-analysis.started': { optional: ['round'] },
|
|
74
|
-
'review-analysis.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round'
|
|
73
|
+
'review-analysis.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round'] },
|
|
75
74
|
'plan.started': { optional: ['round'] },
|
|
76
|
-
'plan.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round'
|
|
75
|
+
'plan.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round'] },
|
|
77
76
|
'review-plan.started': { optional: ['round'] },
|
|
78
|
-
'review-plan.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round'
|
|
77
|
+
'review-plan.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round'] },
|
|
79
78
|
'code.started': { optional: ['round', 'fixFor', 'implementationInput'] },
|
|
80
|
-
'code.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round', 'fixFor', 'implementationInput', 'filesModified', 'testsPassed', 'blockers', 'major', 'minor', 'manualValidation'
|
|
79
|
+
'code.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round', 'fixFor', 'implementationInput', 'filesModified', 'testsPassed', 'blockers', 'major', 'minor', 'manualValidation'] },
|
|
81
80
|
'review-code.started': { optional: ['round'] },
|
|
82
|
-
'review-code.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round'
|
|
81
|
+
'review-code.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round'] },
|
|
83
82
|
'manual-validation.started': { optional: ['round', 'transactionId'] },
|
|
84
83
|
'manual-validation.completed': { required: ['artifact', 'summaryResult', 'transactionId', 'receiptDigest', 'prHeadSha'], optional: ['round'] },
|
|
85
84
|
'validation-run.started': { optional: ['round'] },
|
|
@@ -107,7 +106,7 @@ function validateTaskEventRequest(request) {
|
|
|
107
106
|
}
|
|
108
107
|
if (request.verdict && !['approved', 'changes-requested', 'rejected'].includes(request.verdict))
|
|
109
108
|
return { code: 'EVENT_PAYLOAD_INVALID', message: 'verdict is invalid' };
|
|
110
|
-
if (request.initiator && !['human', 'model'
|
|
109
|
+
if (request.initiator && !['human', 'model'].includes(request.initiator))
|
|
111
110
|
return { code: 'EVENT_PAYLOAD_INVALID', message: 'initiator is invalid' };
|
|
112
111
|
if (request.requestId !== undefined && (!request.requestId.trim() || /[\r\n]/.test(request.requestId)))
|
|
113
112
|
return { code: 'EVENT_PAYLOAD_INVALID', message: 'requestId must be a non-empty single line' };
|
|
@@ -331,21 +330,12 @@ function validateManualValidationCompletion(taskDir, taskId, request, artifactPa
|
|
|
331
330
|
return null;
|
|
332
331
|
}
|
|
333
332
|
function openStartedIdentity(rows, family) {
|
|
334
|
-
const
|
|
333
|
+
const matches = rows.filter((item) => item.family === family);
|
|
335
334
|
if (family === 'manual-validation') {
|
|
336
|
-
const row =
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
const escaped = spec.label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
341
|
-
const pattern = new RegExp(`^${escaped} \\(Round (\\d+)(?:(?:, fix for (review-code(?:-r\\d+)?\\.md))|(?:, decision (II-[1-9]\\d*)))?\\)$`);
|
|
342
|
-
const matches = rows.flatMap((row) => {
|
|
343
|
-
if (!row.started || row.done)
|
|
344
|
-
return [];
|
|
345
|
-
const match = pattern.exec(row.step);
|
|
346
|
-
return match ? [{ row, round: Number(match[1]), fixFor: match[2], implementationInput: match[3] }] : [];
|
|
347
|
-
});
|
|
348
|
-
return matches.length === 1 ? matches[0] : matches.length > 1 ? { conflict: true } : null;
|
|
335
|
+
const row = matches.at(-1);
|
|
336
|
+
return row ? { row, round: row.round, fixFor: undefined, implementationInput: undefined } : null;
|
|
337
|
+
}
|
|
338
|
+
return matches.length === 1 ? { row: matches[0], round: matches[0].round, fixFor: matches[0].fixFor, implementationInput: matches[0].implementationInput } : matches.length > 1 ? { conflict: true } : null;
|
|
349
339
|
}
|
|
350
340
|
function repairMissingCodeFixQualifier(request, family, open, repoRoot) {
|
|
351
341
|
if (family !== 'code' || open.fixFor !== undefined || !request.fixFor || request.implementationInput !== undefined) {
|
|
@@ -369,7 +359,7 @@ function resolveOpenStartedEvent(request, family, open, repoRoot) {
|
|
|
369
359
|
if (open.row.agent !== request.agent)
|
|
370
360
|
return { status: 'error', error: { code: 'EVENT_LOG_CONFLICT', message: 'open started event has a different agent' } };
|
|
371
361
|
if (family === 'manual-validation' && request.transactionId !== undefined) {
|
|
372
|
-
const existingTransactionId =
|
|
362
|
+
const existingTransactionId = open.row.transactionId;
|
|
373
363
|
if (existingTransactionId !== undefined && existingTransactionId !== request.transactionId) {
|
|
374
364
|
return { status: 'error', error: { code: 'EVENT_LOG_CONFLICT', message: 'open manual-validation started event has a different transactionId' } };
|
|
375
365
|
}
|
|
@@ -383,7 +373,7 @@ function resolveOpenStartedEvent(request, family, open, repoRoot) {
|
|
|
383
373
|
return { status: 'error', error: { code: 'EVENT_ARTIFACT_CONFLICT', message: `fixFor '${request.fixFor}' conflicts with open event` } };
|
|
384
374
|
if ('error' in repair)
|
|
385
375
|
return { status: 'error', error: repair.error, context: repair.context };
|
|
386
|
-
return { status: 'repair', repair: repair.request, context: repair.context, superseded: { action: open.row.
|
|
376
|
+
return { status: 'repair', repair: repair.request, context: repair.context, superseded: { action: `${FAMILY[family].label} (Round ${open.round})`, family: open.row.family, round: open.row.round } };
|
|
387
377
|
}
|
|
388
378
|
if (request.implementationInput !== open.implementationInput) {
|
|
389
379
|
return { status: 'error', error: { code: 'EVENT_ARTIFACT_CONFLICT', message: `implementationInput '${request.implementationInput ?? ''}' conflicts with open event` } };
|
|
@@ -397,14 +387,11 @@ function resolveOpenStartedEvent(request, family, open, repoRoot) {
|
|
|
397
387
|
fixFor: open.fixFor,
|
|
398
388
|
implementationInput: open.implementationInput
|
|
399
389
|
},
|
|
400
|
-
startedAt: open.row.
|
|
390
|
+
startedAt: open.row.startedAt
|
|
401
391
|
};
|
|
402
392
|
}
|
|
403
|
-
function hasOtherOpenStarted(rows, allowedAction) {
|
|
404
|
-
return rows.some((row) => row.started && !row.done && row.step !== allowedAction);
|
|
405
|
-
}
|
|
406
393
|
function hasConflictingOpenStarted(rows, recovery) {
|
|
407
|
-
return
|
|
394
|
+
return rows.some((row) => !recovery || row.family !== recovery.family || row.round !== recovery.round);
|
|
408
395
|
}
|
|
409
396
|
function reviewInputFamily(family) {
|
|
410
397
|
return family === 'review-analysis' ? 'analysis' : family === 'review-plan' ? 'plan' : 'code';
|
|
@@ -414,7 +401,7 @@ function lifecycleAction(family) {
|
|
|
414
401
|
}
|
|
415
402
|
function eventTrigger(request, family) {
|
|
416
403
|
return {
|
|
417
|
-
initiator: request.initiator ?? (request.
|
|
404
|
+
initiator: request.initiator ?? (request.agent === 'human' ? 'human' : 'model'),
|
|
418
405
|
requestId: request.requestId ?? `${request.taskRef}:${request.event}:${request.round ?? 1}`,
|
|
419
406
|
requestedAction: lifecycleAction(family),
|
|
420
407
|
reasonCode: request.reasonCode ?? (request.fixFor || request.implementationInput ? 'review-finding' : 'user-request'),
|
|
@@ -422,7 +409,7 @@ function eventTrigger(request, family) {
|
|
|
422
409
|
...(request.sourceArtifact ? { sourceArtifact: request.sourceArtifact } : {}),
|
|
423
410
|
...(request.sourceSha256 ? { sourceSha256: request.sourceSha256 } : {}),
|
|
424
411
|
...(request.implementationInput ? { implementationInput: request.implementationInput } : {}),
|
|
425
|
-
explicitRequest: request.requestId !== undefined || request.reasonCode !== undefined || request.initiator !== undefined
|
|
412
|
+
explicitRequest: request.requestId !== undefined || request.reasonCode !== undefined || request.initiator !== undefined
|
|
426
413
|
};
|
|
427
414
|
}
|
|
428
415
|
function reworkIntentMutationForCompletion(content, taskDir, family, artifact, timestamp) {
|
|
@@ -589,10 +576,14 @@ function applyTaskEvent(request, options = {}) {
|
|
|
589
576
|
catch (error) {
|
|
590
577
|
return failed(request, { code: 'TASK_DOCUMENT_INVALID', message: error instanceof Error ? error.message : String(error) }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
|
|
591
578
|
}
|
|
592
|
-
const section =
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
579
|
+
const section = inspectActivityLog(content).section;
|
|
580
|
+
let rows;
|
|
581
|
+
try {
|
|
582
|
+
rows = lifecycleExecutions(content);
|
|
583
|
+
}
|
|
584
|
+
catch (error) {
|
|
585
|
+
return failed(request, { code: 'EVENT_TRANSITION_INVALID', message: error instanceof Error ? error.message : String(error) }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
|
|
586
|
+
}
|
|
596
587
|
let normalized = request;
|
|
597
588
|
let artifactContext = null;
|
|
598
589
|
let supersededOpenStart = null;
|
|
@@ -631,10 +622,11 @@ function applyTaskEvent(request, options = {}) {
|
|
|
631
622
|
}
|
|
632
623
|
const eventIdentity = identity(normalized);
|
|
633
624
|
const currentStep = typeof frontmatter.current_step === 'string' ? frontmatter.current_step : '';
|
|
634
|
-
const matchingRows = rows.filter((item) => item.step === eventIdentity.action);
|
|
635
625
|
const manual = eventIdentity.family === 'manual-validation';
|
|
636
|
-
const openRows =
|
|
637
|
-
const
|
|
626
|
+
const openRows = rows.filter((item) => item.family === eventIdentity.family && (manual || (item.round === normalized.round && item.fixFor === normalized.fixFor && item.implementationInput === normalized.implementationInput)));
|
|
627
|
+
const completionRecorded = normalized.artifact !== undefined && parseCompletionFacts(frontmatter.completion_facts)
|
|
628
|
+
.some((fact) => fact.event === normalized.event && fact.output === normalized.artifact);
|
|
629
|
+
const hasStartedIdentity = openRows.length > 0;
|
|
638
630
|
if (!manual && openRows.length > 1)
|
|
639
631
|
return failed(normalized, { code: 'EVENT_LOG_CONFLICT', message: 'event identity has more than one open attempt' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase, artifactContext });
|
|
640
632
|
const row = openRows.at(-1);
|
|
@@ -644,14 +636,22 @@ function applyTaskEvent(request, options = {}) {
|
|
|
644
636
|
if (row.agent !== normalized.agent)
|
|
645
637
|
return failed(normalized, { code: 'EVENT_LOG_CONFLICT', message: 'open started event has a different agent' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
|
|
646
638
|
if (manual && normalized.transactionId !== undefined) {
|
|
647
|
-
const existingTransactionId =
|
|
639
|
+
const existingTransactionId = row.transactionId;
|
|
648
640
|
if (existingTransactionId !== undefined && existingTransactionId !== normalized.transactionId) {
|
|
649
641
|
return failed(normalized, { code: 'EVENT_LOG_CONFLICT', message: 'open manual-validation started event has a different transactionId' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
|
|
650
642
|
}
|
|
651
643
|
}
|
|
652
|
-
return successNoOp(normalized, resolved.taskId, resolved.taskMdPath, currentStep, eventIdentity, row.
|
|
653
|
-
}
|
|
654
|
-
|
|
644
|
+
return successNoOp(normalized, resolved.taskId, resolved.taskMdPath, currentStep, eventIdentity, row.startedAt, frontmatter, artifactContext);
|
|
645
|
+
}
|
|
646
|
+
const replayFact = eventIdentity.phase === 'completed' && normalized.artifact && normalized.requestId
|
|
647
|
+
? parseCompletionFacts(frontmatter.completion_facts).find((fact) => fact.event === normalized.event
|
|
648
|
+
&& fact.output === normalized.artifact && fact.requestId === normalized.requestId)
|
|
649
|
+
: undefined;
|
|
650
|
+
const validReplayFact = Boolean(replayFact && normalized.artifact
|
|
651
|
+
&& hasValidArtifactCompletion(content, resolved.taskDir, normalized.artifact, normalized.event));
|
|
652
|
+
const completedByHistory = manual || eventIdentity.family === 'validation-run';
|
|
653
|
+
const completedHistoryReplay = completedByHistory && completionRecorded;
|
|
654
|
+
if (eventIdentity.phase === 'completed' && !hasStartedIdentity && !completedHistoryReplay && !validReplayFact)
|
|
655
655
|
return failed(normalized, { code: 'EVENT_START_MISSING', message: 'completion requires a started event or an earlier completed attempt' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
|
|
656
656
|
if (eventIdentity.phase === 'completed') {
|
|
657
657
|
const validated = validateCompletedArtifact(resolved.taskDir, FAMILY[eventIdentity.family].artifact, normalized.artifact, normalized.round);
|
|
@@ -711,10 +711,6 @@ function applyTaskEvent(request, options = {}) {
|
|
|
711
711
|
}
|
|
712
712
|
}
|
|
713
713
|
}
|
|
714
|
-
if (eventIdentity.phase === 'waiting' && section.entries.some((entry) => entry.step === eventIdentity.action && entry.note === eventIdentity.note)) {
|
|
715
|
-
const existing = section.entries.find((entry) => entry.step === eventIdentity.action && entry.note === eventIdentity.note);
|
|
716
|
-
return successNoOp(normalized, resolved.taskId, resolved.taskMdPath, currentStep, eventIdentity, existing.time, frontmatter, artifactContext);
|
|
717
|
-
}
|
|
718
714
|
if (eventIdentity.phase === 'started') {
|
|
719
715
|
const trigger = eventTrigger(normalized, eventIdentity.family);
|
|
720
716
|
const facts = buildLifecycleFacts(resolved.taskDir, content, resolved.state, false, resolved.repoRoot);
|
|
@@ -723,7 +719,7 @@ function applyTaskEvent(request, options = {}) {
|
|
|
723
719
|
const capability = canStart(lifecycleAction(eventIdentity.family), facts.facts, trigger);
|
|
724
720
|
const safetyFailure = capability.reasonCode === 'TASK_NOT_ACTIVE'
|
|
725
721
|
|| capability.reasonCode === 'LIFECYCLE_EXECUTION_OPEN';
|
|
726
|
-
if (!capability.allowed &&
|
|
722
|
+
if (!capability.allowed && safetyFailure
|
|
727
723
|
&& !(supersededOpenStart && capability.reasonCode === 'LIFECYCLE_EXECUTION_OPEN')) {
|
|
728
724
|
return failed(normalized, { code: 'EVENT_TRANSITION_INVALID', message: `${capability.reasonCode}: ${capability.evidence.join(', ')}` }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
|
|
729
725
|
}
|
|
@@ -731,29 +727,6 @@ function applyTaskEvent(request, options = {}) {
|
|
|
731
727
|
const findingCountError = validateReviewFindingCounts(normalized, content, eventIdentity.family, completedArtifact?.path ?? null);
|
|
732
728
|
if (findingCountError)
|
|
733
729
|
return failed(normalized, findingCountError, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
|
|
734
|
-
let orchestrationCompletion = null;
|
|
735
|
-
if (eventIdentity.phase === 'completed' && normalized.orchestrated
|
|
736
|
-
&& eventIdentity.family !== 'manual-validation' && eventIdentity.family !== 'validation-run') {
|
|
737
|
-
const orchestrationStage = eventIdentity.family === 'analyze' ? 'analysis' : eventIdentity.family;
|
|
738
|
-
const execution = validateLifecycleExecution(normalized.taskRef, {
|
|
739
|
-
mode: 'orchestrated',
|
|
740
|
-
identity: {
|
|
741
|
-
stage: orchestrationStage,
|
|
742
|
-
round: normalized.round,
|
|
743
|
-
artifact: normalized.artifact,
|
|
744
|
-
role: eventIdentity.family.startsWith('review-') ? 'reviewer' : 'executor'
|
|
745
|
-
},
|
|
746
|
-
agent: normalized.agent,
|
|
747
|
-
dryRun: normalized.dryRun
|
|
748
|
-
}, { repoRoot: options.repoRoot });
|
|
749
|
-
if (!execution.ok) {
|
|
750
|
-
return failed(normalized, {
|
|
751
|
-
code: 'EVENT_TRANSITION_INVALID',
|
|
752
|
-
message: `${execution.error?.code ?? 'ORCHESTRATION_PROVENANCE_MISMATCH'}: ${execution.error?.message ?? 'orchestration provenance validation failed'}`
|
|
753
|
-
}, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase, artifactContext });
|
|
754
|
-
}
|
|
755
|
-
orchestrationCompletion = execution.completionPlan;
|
|
756
|
-
}
|
|
757
730
|
let metadata;
|
|
758
731
|
try {
|
|
759
732
|
metadata = (options.metadataProvider ?? captureTaskWriteMetadata)();
|
|
@@ -782,6 +755,9 @@ function applyTaskEvent(request, options = {}) {
|
|
|
782
755
|
if (parseCompletionFacts(frontmatter.completion_facts).some((fact) => sameCompletionFact(fact, currentFact))) {
|
|
783
756
|
return successNoOp(normalized, resolved.taskId, resolved.taskMdPath, currentStep, eventIdentity, completionReceipts[0]?.completedAt ?? metadata.timestamp, frontmatter, artifactContext);
|
|
784
757
|
}
|
|
758
|
+
if (!hasStartedIdentity && !completedHistoryReplay) {
|
|
759
|
+
return failed(normalized, { code: 'EVENT_START_MISSING', message: 'completion replay does not match the existing completion fact' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
|
|
760
|
+
}
|
|
785
761
|
try {
|
|
786
762
|
const rework = reworkIntentMutationForCompletion(content, resolved.taskDir, eventIdentity.family, completedArtifact, metadata.timestamp);
|
|
787
763
|
if ('error' in rework)
|
|
@@ -794,16 +770,22 @@ function applyTaskEvent(request, options = {}) {
|
|
|
794
770
|
}
|
|
795
771
|
const step = eventIdentity.phase === 'started' || eventIdentity.target === null ? currentStep : eventIdentity.target;
|
|
796
772
|
const logStep = eventIdentity.phase === 'started' ? `${eventIdentity.action} [started]` : eventIdentity.action;
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
:
|
|
805
|
-
|
|
773
|
+
let body = null;
|
|
774
|
+
if (section) {
|
|
775
|
+
const supersededBody = supersededOpenStart
|
|
776
|
+
? appendActivityEntry(section, {
|
|
777
|
+
time: metadata.timestamp, step: `${supersededOpenStart.action} [aborted]`,
|
|
778
|
+
agent: normalized.agent, note: `superseded by ${eventIdentity.action}`
|
|
779
|
+
}) : section.body;
|
|
780
|
+
body = appendActivityEntry({ ...section, body: supersededBody }, { time: metadata.timestamp, step: logStep, agent: normalized.agent, note: eventIdentity.note });
|
|
781
|
+
}
|
|
806
782
|
const frontmatterSet = { current_step: step, assigned_to: normalized.agent };
|
|
783
|
+
if (eventIdentity.phase === 'started' || eventIdentity.phase === 'completed') {
|
|
784
|
+
const open = rows.filter((item) => !openRows.includes(item) && (!supersededOpenStart || item.family !== supersededOpenStart.family || item.round !== supersededOpenStart.round));
|
|
785
|
+
if (eventIdentity.phase === 'started')
|
|
786
|
+
open.push({ family: eventIdentity.family, agent: normalized.agent, startedAt: metadata.timestamp, round: normalized.round, fixFor: normalized.fixFor, implementationInput: normalized.implementationInput, transactionId: normalized.transactionId });
|
|
787
|
+
frontmatterSet.lifecycle_execution = serializeLifecycleExecution(open, content);
|
|
788
|
+
}
|
|
807
789
|
if (currentFact)
|
|
808
790
|
frontmatterSet.completion_facts = JSON.stringify(replaceCompletionFact(parseCompletionFacts(frontmatter.completion_facts), currentFact));
|
|
809
791
|
if (completedArtifact && ['analyze', 'plan', 'code'].includes(eventIdentity.family)) {
|
|
@@ -869,7 +851,7 @@ function applyTaskEvent(request, options = {}) {
|
|
|
869
851
|
if (eventIdentity.phase === 'started' && normalized.implementationInput)
|
|
870
852
|
frontmatterSet.last_reviewed_commit = '';
|
|
871
853
|
const mutations = [
|
|
872
|
-
{ kind: 'frontmatter', set: frontmatterSet, remove: frontmatterRemove }
|
|
854
|
+
{ kind: 'frontmatter', set: frontmatterSet, remove: frontmatterRemove, ...(frontmatterSet.lifecycle_execution ? { lifecycleExecutionDomain: 'ordinary' } : {}) }
|
|
873
855
|
];
|
|
874
856
|
if (completedArtifact) {
|
|
875
857
|
const link = buildArtifactLinkSection(content, completedArtifact);
|
|
@@ -901,32 +883,11 @@ function applyTaskEvent(request, options = {}) {
|
|
|
901
883
|
body: renderImplementationInputs(implementationRows)
|
|
902
884
|
});
|
|
903
885
|
}
|
|
904
|
-
|
|
886
|
+
if (section && body !== null)
|
|
887
|
+
mutations.push({ kind: 'section', aliases: ['活动日志', 'Activity Log'], heading: section.heading, body });
|
|
905
888
|
const result = writeTask({ taskRef: normalized.taskRef, expectedState: 'active', dryRun: normalized.dryRun, mutations }, { ...options, metadataProvider: () => metadata });
|
|
906
889
|
if (result.status === 'failed')
|
|
907
890
|
return failed(normalized, result.error, { taskId: result.taskId, taskMdPath: result.taskMdPath, fromStep: currentStep, toStep: step, action: eventIdentity.action, phase: eventIdentity.phase, timestamp: result.timestamp, agentInfraVersion: result.agentInfraVersion, operations: result.operations, artifactContext });
|
|
908
|
-
if (!normalized.dryRun && orchestrationCompletion) {
|
|
909
|
-
try {
|
|
910
|
-
(options.commitOrchestrationCompletion ?? commitOrchestrationStageCompletion)(orchestrationCompletion);
|
|
911
|
-
}
|
|
912
|
-
catch (error) {
|
|
913
|
-
return failed(normalized, {
|
|
914
|
-
code: 'EVENT_ORCHESTRATION_COMMIT_FAILED',
|
|
915
|
-
message: `task.md was written but orchestration completion could not be persisted; manual recovery is required: ${error instanceof Error ? error.message : String(error)}`
|
|
916
|
-
}, {
|
|
917
|
-
taskId: result.taskId,
|
|
918
|
-
taskMdPath: result.taskMdPath,
|
|
919
|
-
fromStep: currentStep,
|
|
920
|
-
toStep: step,
|
|
921
|
-
action: eventIdentity.action,
|
|
922
|
-
phase: eventIdentity.phase,
|
|
923
|
-
timestamp: result.timestamp,
|
|
924
|
-
agentInfraVersion: result.agentInfraVersion,
|
|
925
|
-
operations: result.operations,
|
|
926
|
-
artifactContext
|
|
927
|
-
});
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
891
|
return {
|
|
931
892
|
status: result.status, changed: result.changed, event: normalized.event,
|
|
932
893
|
requestRef: normalized.taskRef, taskId: result.taskId, taskMdPath: result.taskMdPath,
|
|
@@ -946,5 +907,21 @@ function successNoOp(request, taskId, taskMdPath, currentStep, eventIdentity, ti
|
|
|
946
907
|
artifactContext
|
|
947
908
|
};
|
|
948
909
|
}
|
|
949
|
-
|
|
910
|
+
function applyTaskEventWithWarnings(request, options = {}) {
|
|
911
|
+
const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
|
|
912
|
+
let warnings = [];
|
|
913
|
+
if (resolved.ok) {
|
|
914
|
+
try {
|
|
915
|
+
const inspected = inspectActivityLog(fs.readFileSync(resolved.taskMdPath, 'utf8'));
|
|
916
|
+
if (!inspected.section)
|
|
917
|
+
warnings = [{ code: 'ACTIVITY_LOG_UNAVAILABLE', message: 'Activity Log is missing or ambiguous; no entry was appended' }];
|
|
918
|
+
else if (inspected.invalidEntries.length)
|
|
919
|
+
warnings = [{ code: 'ACTIVITY_LOG_INVALID_ENTRIES', message: 'Activity Log contains malformed entries' }];
|
|
920
|
+
}
|
|
921
|
+
catch { /* The core reports task read errors. */ }
|
|
922
|
+
}
|
|
923
|
+
const result = applyTaskEvent(request, options);
|
|
924
|
+
return result.status === 'failed' || warnings.length === 0 ? result : { ...result, warnings };
|
|
925
|
+
}
|
|
926
|
+
export { eventCatalog, validateTaskEventRequest, applyTaskEventWithWarnings as applyTaskEvent };
|
|
950
927
|
//# sourceMappingURL=events.js.map
|
|
@@ -7,6 +7,7 @@ import { backfillCompletionComments, inspectCompletionBackfillEligibility } from
|
|
|
7
7
|
import { taskIssueIdentity } from '../platform/task-identities.js';
|
|
8
8
|
import { inspectPlatformIssue, syncPlatformIssue } from '../platform/issues.js';
|
|
9
9
|
import { resourceIdentityEquals } from '../platform/resource-identity.js';
|
|
10
|
+
import { activityWarnings } from './activity-log.js';
|
|
10
11
|
import { parseTaskFrontmatter } from './frontmatter.js';
|
|
11
12
|
import { recoverPlatformOperations } from './platform-operation-recovery.js';
|
|
12
13
|
import { applyTaskLifecycle, inspectTaskLifecycleProgress, previewTaskCompletion } from './lifecycle.js';
|
|
@@ -207,7 +208,8 @@ function lifecycleStep(result) {
|
|
|
207
208
|
changed: result.changed,
|
|
208
209
|
error: result.error ? errorOf(result.error, 'LIFECYCLE_FAILED') : null,
|
|
209
210
|
completedSteps: result.completedSteps ?? [],
|
|
210
|
-
pendingSteps: result.pendingSteps ?? []
|
|
211
|
+
pendingSteps: result.pendingSteps ?? [],
|
|
212
|
+
warnings: (result.warnings ?? []).map((warning) => ({ ...warning, step: 'lifecycle', target: 'activity-log', severity: 'IMPORTANT', retryable: true }))
|
|
211
213
|
};
|
|
212
214
|
}
|
|
213
215
|
function commentStep(result) {
|
|
@@ -221,7 +223,18 @@ function verificationStep(result) {
|
|
|
221
223
|
return {
|
|
222
224
|
status: result.status,
|
|
223
225
|
changed: false,
|
|
224
|
-
error: result.status === 'pass' ? null : verificationFailure(result)
|
|
226
|
+
error: result.status === 'pass' ? null : verificationFailure(result),
|
|
227
|
+
warnings: result.invocations.flatMap(({ payload }) => {
|
|
228
|
+
const checks = Array.isArray(payload.checks) ? payload.checks : [payload];
|
|
229
|
+
return checks.flatMap((check) => {
|
|
230
|
+
if (!check || typeof check !== 'object' || !Array.isArray(check.warnings))
|
|
231
|
+
return [];
|
|
232
|
+
return check.warnings.filter((message) => typeof message === 'string').map((message) => ({
|
|
233
|
+
code: 'VERIFICATION_DIAGNOSTIC', message, retryable: true, step: 'verification',
|
|
234
|
+
target: typeof check.checkId === 'string' ? check.checkId : String(check.type ?? 'check'), severity: 'IMPORTANT'
|
|
235
|
+
}));
|
|
236
|
+
});
|
|
237
|
+
})
|
|
225
238
|
};
|
|
226
239
|
}
|
|
227
240
|
function verificationFailure(result) {
|
|
@@ -351,7 +364,7 @@ function issueCapability(receipt, scope) {
|
|
|
351
364
|
}
|
|
352
365
|
function capabilityError(code, message) {
|
|
353
366
|
const error = new Error(message);
|
|
354
|
-
error.name = '
|
|
367
|
+
error.name = 'TaskFinalizationCapabilityError';
|
|
355
368
|
Object.assign(error, { code });
|
|
356
369
|
return error;
|
|
357
370
|
}
|
|
@@ -648,7 +661,7 @@ async function syncPendingSummary(input) {
|
|
|
648
661
|
function terminalResult(taskId, receipt, steps, changed, error = null) {
|
|
649
662
|
const pending = pendingSteps(receipt);
|
|
650
663
|
const blocked = [steps.backfill, steps.lifecycle, steps.taskComment, steps.verification, steps.summary].some((step) => step?.status === 'blocked');
|
|
651
|
-
const warnings = openWarnings(receipt);
|
|
664
|
+
const warnings = mergeOperationWarnings(openWarnings(receipt), steps.lifecycle?.warnings ?? [], steps.verification?.warnings ?? []);
|
|
652
665
|
const postLifecyclePending = receipt.lifecycle === 'done' && (pending.some((step) => step !== 'lifecycle') || receipt.warningProjection === 'pending');
|
|
653
666
|
const terminalVerificationPending = receipt.lifecycle === 'done' && receipt.verification === 'pending';
|
|
654
667
|
const resultError = error ?? (terminalVerificationPending ? steps.verification?.error : null) ?? null;
|
|
@@ -687,7 +700,7 @@ function preparedResult(taskId, receipt, steps, changed) {
|
|
|
687
700
|
verification: steps.verification ?? null,
|
|
688
701
|
summary: steps.summary ?? null,
|
|
689
702
|
completedSteps: completedSteps(receipt), pendingSteps: pendingSteps(receipt),
|
|
690
|
-
result: 'prepared', warnings: openWarnings(receipt), error: null
|
|
703
|
+
result: 'prepared', warnings: mergeOperationWarnings(openWarnings(receipt), steps.lifecycle?.warnings ?? []), error: null
|
|
691
704
|
};
|
|
692
705
|
}
|
|
693
706
|
async function prepareTaskFinalizationCore(request, taskId, options) {
|
|
@@ -965,7 +978,7 @@ async function prepareTaskFinalizationCore(request, taskId, options) {
|
|
|
965
978
|
}
|
|
966
979
|
return preparedResult(taskId, receipt, { backfill: backfillResult, lifecycle: lifecycleResult, taskComment, verification, summary: summary.step }, changed);
|
|
967
980
|
}
|
|
968
|
-
async function
|
|
981
|
+
async function prepareTaskFinalizationInner(request, options) {
|
|
969
982
|
if (request.intent !== 'complete' || !request.taskRef || !request.agent) {
|
|
970
983
|
return failed(null, { code: 'TASK_FINALIZATION_PAYLOAD_INVALID', message: 'complete finalization requires taskRef and agent', retryable: false });
|
|
971
984
|
}
|
|
@@ -1144,6 +1157,28 @@ async function commitPreparedTaskFinalization(request, options) {
|
|
|
1144
1157
|
return failed(resolved.taskId, detail);
|
|
1145
1158
|
}
|
|
1146
1159
|
}
|
|
1160
|
+
function withActivityWarnings(result, request, options) {
|
|
1161
|
+
if (result.status === 'failed' || result.status === 'blocked')
|
|
1162
|
+
return result;
|
|
1163
|
+
const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
|
|
1164
|
+
if (!resolved.ok)
|
|
1165
|
+
return result;
|
|
1166
|
+
let diagnostics;
|
|
1167
|
+
try {
|
|
1168
|
+
diagnostics = activityWarnings(fs.readFileSync(resolved.taskMdPath, 'utf8'));
|
|
1169
|
+
}
|
|
1170
|
+
catch {
|
|
1171
|
+
return result;
|
|
1172
|
+
}
|
|
1173
|
+
const warnings = diagnostics.map((warning) => ({ ...warning, step: 'lifecycle', target: 'activity-log', severity: 'IMPORTANT', retryable: true }));
|
|
1174
|
+
return { ...result, warnings: mergeOperationWarnings(result.warnings, warnings) };
|
|
1175
|
+
}
|
|
1176
|
+
async function prepareTaskFinalization(request, options) {
|
|
1177
|
+
return withActivityWarnings(await prepareTaskFinalizationInner(request, options), request, options);
|
|
1178
|
+
}
|
|
1179
|
+
async function commitPreparedTaskFinalizationWithWarnings(request, options) {
|
|
1180
|
+
return withActivityWarnings(await commitPreparedTaskFinalization(request, options), request, options);
|
|
1181
|
+
}
|
|
1147
1182
|
async function applyTaskFinalization(request, options) {
|
|
1148
1183
|
const prepared = await prepareTaskFinalization(request, options);
|
|
1149
1184
|
if (prepared.status !== 'prepared')
|
|
@@ -1162,7 +1197,8 @@ async function applyTaskFinalization(request, options) {
|
|
|
1162
1197
|
});
|
|
1163
1198
|
}
|
|
1164
1199
|
}
|
|
1165
|
-
|
|
1200
|
+
const committed = await commitPreparedTaskFinalizationWithWarnings(request, options);
|
|
1201
|
+
return { ...committed, warnings: mergeOperationWarnings(prepared.warnings, committed.warnings) };
|
|
1166
1202
|
}
|
|
1167
|
-
export { applyFinalizationReceiptMutation, commitPreparedTaskFinalization, applyTaskFinalization, prepareTaskFinalization, issueCapability as createFinalizationCapability, readTaskFinalizationReceipt, terminalResult };
|
|
1203
|
+
export { applyFinalizationReceiptMutation, commitPreparedTaskFinalizationWithWarnings as commitPreparedTaskFinalization, applyTaskFinalization, prepareTaskFinalization, issueCapability as createFinalizationCapability, readTaskFinalizationReceipt, terminalResult };
|
|
1168
1204
|
//# sourceMappingURL=finalization.js.map
|
|
@@ -7,7 +7,7 @@ import { LEDGER_COLUMNS, LEDGER_HEADINGS, LEDGER_SECTION_MISSING_CODE, LEDGER_SE
|
|
|
7
7
|
import { resolveTaskRef } from './resolve-ref.js';
|
|
8
8
|
import { writeTask } from './write.js';
|
|
9
9
|
import { parseLegacyReworkIntentDocument, parseReworkIntentDocument, reworkIntentMutation, upsertReworkIntent } from './rework-intent.js';
|
|
10
|
-
import { extractSection
|
|
10
|
+
import { extractSection } from './sections.js';
|
|
11
11
|
import { parseLifecyclePathDecision } from './lifecycle-path.js';
|
|
12
12
|
import { scanVisibleMarkdown } from './markdown.js';
|
|
13
13
|
import { inspectArtifactDirectory } from './artifact-lifecycle.js';
|