@pellux/goodvibes-agent 1.1.6 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +176 -0
- package/README.md +46 -30
- package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
- package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
- package/dist/package/main.js +132662 -91399
- package/docs/README.md +14 -7
- package/docs/channels-remote-and-api.md +8 -5
- package/docs/connected-host.md +14 -12
- package/docs/getting-started.md +56 -30
- package/docs/knowledge-artifacts-and-multimodal.md +7 -5
- package/docs/project-planning.md +2 -2
- package/docs/providers-and-routing.md +11 -3
- package/docs/tools-and-commands.md +114 -45
- package/docs/voice-and-live-tts.md +3 -1
- package/package.json +3 -2
- package/release/release-notes.md +130 -5
- package/release/release-readiness.json +120 -90
- package/src/agent/assistant-cockpit.ts +247 -0
- package/src/agent/autonomy-schedule-format.ts +96 -0
- package/src/agent/autonomy-schedule.ts +514 -0
- package/src/agent/channel-delivery-receipts.ts +292 -0
- package/src/agent/competitive-feature-inventory.ts +296 -0
- package/src/agent/document-registry-types.ts +106 -0
- package/src/agent/document-registry.ts +734 -0
- package/src/agent/harness-control.ts +2 -2
- package/src/agent/memory-prompt.ts +2 -2
- package/src/agent/operator-actions.ts +50 -6
- package/src/agent/persona-registry.ts +8 -0
- package/src/agent/project-context-files.ts +273 -0
- package/src/agent/prompt-context-receipts.ts +502 -0
- package/src/agent/reminder-schedule-format.ts +16 -2
- package/src/agent/research-run-registry.ts +582 -0
- package/src/agent/research-source-registry.ts +441 -0
- package/src/agent/routine-registry.ts +19 -3
- package/src/agent/routine-schedule-format.ts +27 -2
- package/src/agent/runtime-profile-starters.ts +7 -0
- package/src/agent/runtime-profile.ts +106 -4
- package/src/agent/schedule-edit-format.ts +129 -0
- package/src/agent/schedule-edit.ts +496 -0
- package/src/agent/schedule-next-routes.ts +42 -0
- package/src/agent/setup-wizard-checkpoint.ts +140 -0
- package/src/agent/setup-wizard.ts +447 -0
- package/src/agent/skill-registry-types.ts +102 -0
- package/src/agent/skill-registry.ts +81 -107
- package/src/agent/vibe-confirmation-routes.ts +62 -0
- package/src/agent/vibe-file.ts +285 -0
- package/src/cli/agent-knowledge-command.ts +45 -2
- package/src/cli/help.ts +3 -0
- package/src/cli/profiles-command.ts +25 -11
- package/src/config/agent-settings-policy.ts +1 -18
- package/src/input/agent-workspace-activation.ts +53 -0
- package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
- package/src/input/agent-workspace-artifact-metadata.ts +17 -0
- package/src/input/agent-workspace-basic-command-editors.ts +5 -1
- package/src/input/agent-workspace-categories.ts +153 -155
- package/src/input/agent-workspace-channel-triage.ts +481 -0
- package/src/input/agent-workspace-channels.ts +263 -0
- package/src/input/agent-workspace-command-editor.ts +152 -0
- package/src/input/agent-workspace-context-snapshot.ts +349 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
- package/src/input/agent-workspace-document-editor.ts +502 -0
- package/src/input/agent-workspace-document-ops-editor.ts +523 -0
- package/src/input/agent-workspace-host-category.ts +1 -1
- package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
- package/src/input/agent-workspace-model-compare-editor.ts +376 -0
- package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
- package/src/input/agent-workspace-model-compare-types.ts +82 -0
- package/src/input/agent-workspace-model-compare-utils.ts +35 -0
- package/src/input/agent-workspace-onboarding-categories.ts +141 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
- package/src/input/agent-workspace-operations-command-editors.ts +22 -0
- package/src/input/agent-workspace-research-report-editor.ts +212 -0
- package/src/input/agent-workspace-research-run-editor.ts +144 -0
- package/src/input/agent-workspace-research-source-editor.ts +167 -0
- package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
- package/src/input/agent-workspace-review-packet-utils.ts +265 -0
- package/src/input/agent-workspace-settings.ts +262 -30
- package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
- package/src/input/agent-workspace-setup-snapshot.ts +198 -0
- package/src/input/agent-workspace-setup.ts +34 -1
- package/src/input/agent-workspace-snapshot.ts +162 -147
- package/src/input/agent-workspace-types.ts +287 -2
- package/src/input/agent-workspace.ts +18 -0
- package/src/input/command-registry.ts +9 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
- package/src/input/commands/channels-runtime.ts +102 -114
- package/src/input/commands/delegation-runtime.ts +87 -24
- package/src/input/commands/knowledge-browser-flags.ts +12 -0
- package/src/input/commands/knowledge.ts +28 -14
- package/src/input/commands/operator-actions-runtime.ts +6 -3
- package/src/input/commands/schedule-runtime.ts +71 -14
- package/src/input/commands/session-content.ts +2 -2
- package/src/input/commands/shell-core.ts +2 -0
- package/src/input/commands/vibe-runtime.ts +140 -0
- package/src/input/commands.ts +2 -0
- package/src/input/connected-host-routes.ts +123 -0
- package/src/input/settings-modal-types.ts +14 -0
- package/src/main.ts +15 -15
- package/src/panels/qr-panel.ts +2 -2
- package/src/renderer/agent-workspace-context-lines.ts +686 -0
- package/src/renderer/agent-workspace.ts +30 -419
- package/src/renderer/settings-modal-helpers.ts +12 -0
- package/src/renderer/settings-modal.ts +12 -0
- package/src/runtime/bootstrap-command-context.ts +11 -1
- package/src/runtime/bootstrap-command-parts.ts +14 -3
- package/src/runtime/bootstrap-core.ts +43 -1
- package/src/runtime/bootstrap-shell.ts +6 -0
- package/src/runtime/bootstrap.ts +113 -30
- package/src/runtime/connected-host-auth.ts +3 -2
- package/src/runtime/execution-ledger.ts +231 -0
- package/src/runtime/services.ts +88 -10
- package/src/runtime/tool-permission-safety.ts +287 -0
- package/src/shell/session-continuity-hints.ts +39 -0
- package/src/tools/agent-artifacts-tool.ts +606 -0
- package/src/tools/agent-audit-tool.ts +155 -0
- package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
- package/src/tools/agent-autonomy-tool.ts +140 -0
- package/src/tools/agent-channel-send-tool.ts +24 -2
- package/src/tools/agent-channels-tool.ts +140 -0
- package/src/tools/agent-computer-tool.ts +168 -0
- package/src/tools/agent-context-policy.ts +267 -10
- package/src/tools/agent-context-tool.ts +143 -0
- package/src/tools/agent-delegation-tool.ts +128 -0
- package/src/tools/agent-device-tool.ts +240 -0
- package/src/tools/agent-documents-tool.ts +684 -0
- package/src/tools/agent-execution-tool.ts +230 -0
- package/src/tools/agent-harness-agent-orchestration.ts +703 -0
- package/src/tools/agent-harness-autonomy-intake.ts +785 -0
- package/src/tools/agent-harness-autonomy-live-records.ts +588 -0
- package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
- package/src/tools/agent-harness-autonomy-queue.ts +560 -0
- package/src/tools/agent-harness-background-processes-types.ts +35 -0
- package/src/tools/agent-harness-background-processes.ts +794 -0
- package/src/tools/agent-harness-browser-cockpit-route.ts +219 -0
- package/src/tools/agent-harness-browser-control.ts +338 -0
- package/src/tools/agent-harness-channel-metadata.ts +168 -10
- package/src/tools/agent-harness-cli-command-policy.ts +110 -0
- package/src/tools/agent-harness-command-catalog.ts +4 -2
- package/src/tools/agent-harness-command-runner.ts +42 -0
- package/src/tools/agent-harness-connected-host-status.ts +7 -4
- package/src/tools/agent-harness-delegation-posture.ts +234 -19
- package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
- package/src/tools/agent-harness-document-ops-types.ts +72 -0
- package/src/tools/agent-harness-document-ops.ts +671 -0
- package/src/tools/agent-harness-execution-history.ts +489 -0
- package/src/tools/agent-harness-execution-posture.ts +382 -0
- package/src/tools/agent-harness-file-recovery.ts +135 -0
- package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
- package/src/tools/agent-harness-learning-curator-common.ts +102 -0
- package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
- package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
- package/src/tools/agent-harness-learning-curator-types.ts +151 -0
- package/src/tools/agent-harness-learning-curator.ts +417 -0
- package/src/tools/agent-harness-local-model-benchmarks.ts +199 -0
- package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
- package/src/tools/agent-harness-local-model-endpoints.ts +673 -0
- package/src/tools/agent-harness-media-posture.ts +208 -2
- package/src/tools/agent-harness-memory-posture.ts +556 -0
- package/src/tools/agent-harness-metadata.ts +100 -168
- package/src/tools/agent-harness-mode-catalog.ts +84 -33
- package/src/tools/agent-harness-model-catalog.ts +162 -0
- package/src/tools/agent-harness-model-provider-health.ts +186 -0
- package/src/tools/agent-harness-model-readiness.ts +406 -0
- package/src/tools/agent-harness-model-routing-types.ts +266 -0
- package/src/tools/agent-harness-model-routing-utils.ts +30 -0
- package/src/tools/agent-harness-model-routing.ts +137 -190
- package/src/tools/agent-harness-operator-methods.ts +115 -133
- package/src/tools/agent-harness-pairing-posture.ts +431 -18
- package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
- package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
- package/src/tools/agent-harness-personal-ops-lanes.ts +204 -0
- package/src/tools/agent-harness-personal-ops-records.ts +732 -0
- package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
- package/src/tools/agent-harness-personal-ops-types.ts +222 -0
- package/src/tools/agent-harness-personal-ops.ts +606 -0
- package/src/tools/agent-harness-project-context.ts +144 -0
- package/src/tools/agent-harness-prompt-context.ts +589 -0
- package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
- package/src/tools/agent-harness-release-evidence.ts +9 -7
- package/src/tools/agent-harness-release-readiness.ts +9 -7
- package/src/tools/agent-harness-research-briefing.ts +427 -0
- package/src/tools/agent-harness-research-queue.ts +250 -0
- package/src/tools/agent-harness-research-runs.ts +295 -0
- package/src/tools/agent-harness-research-workflow.ts +322 -0
- package/src/tools/agent-harness-security-posture.ts +2 -2
- package/src/tools/agent-harness-service-posture.ts +9 -9
- package/src/tools/agent-harness-session-metadata.ts +3 -3
- package/src/tools/agent-harness-setup-connected-host.ts +501 -0
- package/src/tools/agent-harness-setup-describe.ts +557 -0
- package/src/tools/agent-harness-setup-handoffs.ts +502 -0
- package/src/tools/agent-harness-setup-model-helpers.ts +101 -0
- package/src/tools/agent-harness-setup-plan.ts +253 -0
- package/src/tools/agent-harness-setup-posture-types.ts +218 -0
- package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
- package/src/tools/agent-harness-setup-posture.ts +449 -221
- package/src/tools/agent-harness-setup-smoke.ts +508 -0
- package/src/tools/agent-harness-sudo-posture.ts +114 -0
- package/src/tools/agent-harness-tool-schema.ts +120 -7
- package/src/tools/agent-harness-tool-types.ts +78 -0
- package/src/tools/agent-harness-tool-utils.ts +43 -0
- package/src/tools/agent-harness-tool.ts +311 -370
- package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
- package/src/tools/agent-harness-ui-surface-types.ts +46 -0
- package/src/tools/agent-harness-vibe-health.ts +105 -0
- package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
- package/src/tools/agent-harness-workspace-actions.ts +114 -8
- package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
- package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
- package/src/tools/agent-host-tool.ts +159 -0
- package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
- package/src/tools/agent-learning-consolidation-core.ts +327 -0
- package/src/tools/agent-learning-consolidation-tool.ts +758 -0
- package/src/tools/agent-memory-tool.ts +214 -0
- package/src/tools/agent-model-compare-export.ts +315 -0
- package/src/tools/agent-model-compare-handoff.ts +592 -0
- package/src/tools/agent-model-compare-judgment.ts +633 -0
- package/src/tools/agent-model-compare-run.ts +722 -0
- package/src/tools/agent-model-compare-tool.ts +698 -0
- package/src/tools/agent-model-compare-types.ts +191 -0
- package/src/tools/agent-model-compare-utils.ts +93 -0
- package/src/tools/agent-models-tool.ts +208 -0
- package/src/tools/agent-operator-action-tool.ts +1 -1
- package/src/tools/agent-operator-method-tool.ts +643 -0
- package/src/tools/agent-personal-ops-tool.ts +197 -0
- package/src/tools/agent-policy-explanation.ts +415 -0
- package/src/tools/agent-research-report-tool.ts +608 -0
- package/src/tools/agent-research-runs-tool.ts +434 -0
- package/src/tools/agent-research-sources-tool.ts +443 -0
- package/src/tools/agent-research-tool.ts +687 -0
- package/src/tools/agent-review-packet-presets-core.ts +757 -0
- package/src/tools/agent-review-packet-presets-tool.ts +466 -0
- package/src/tools/agent-review-packet-share-tool.ts +305 -0
- package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
- package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
- package/src/tools/agent-route-planner-candidates-work.ts +251 -0
- package/src/tools/agent-route-planner-helpers.ts +667 -0
- package/src/tools/agent-route-planner.ts +185 -0
- package/src/tools/agent-route-tool.ts +105 -0
- package/src/tools/agent-schedule-edit-tool.ts +210 -0
- package/src/tools/agent-schedule-tool.ts +282 -0
- package/src/tools/agent-security-tool.ts +145 -0
- package/src/tools/agent-sessions-tool.ts +122 -0
- package/src/tools/agent-settings-import-tool.ts +104 -0
- package/src/tools/agent-settings-tool.ts +176 -0
- package/src/tools/agent-setup-tool.ts +226 -0
- package/src/tools/agent-support-tool.ts +122 -0
- package/src/tools/agent-terminal-process-tools.ts +167 -0
- package/src/tools/agent-tool-policy-guard-types.ts +77 -0
- package/src/tools/agent-tool-policy-guard.ts +110 -89
- package/src/tools/agent-vibe-tool.ts +297 -0
- package/src/tools/agent-work-plan-tool.ts +265 -6
- package/src/tools/agent-workspace-tool.ts +305 -0
- package/src/tools/artifact-archive.ts +169 -0
- package/src/tools/tool-definition-compaction.ts +36 -0
- package/src/tools/tool-execution-safety.ts +41 -0
- package/src/version.ts +1 -1
|
@@ -21,6 +21,13 @@ interface DelegationRoute {
|
|
|
21
21
|
readonly label: string;
|
|
22
22
|
readonly detail: string;
|
|
23
23
|
readonly effect: 'read-only' | 'main-conversation' | 'delegated-work' | 'blocked';
|
|
24
|
+
readonly lane?: DelegationLaneId;
|
|
25
|
+
readonly bestFor?: readonly string[];
|
|
26
|
+
readonly requiredFields?: readonly string[];
|
|
27
|
+
readonly optionalFields?: readonly string[];
|
|
28
|
+
readonly successEvidence?: readonly string[];
|
|
29
|
+
readonly statusRoutes?: readonly string[];
|
|
30
|
+
readonly recoveryRoutes?: readonly string[];
|
|
24
31
|
readonly command?: string;
|
|
25
32
|
readonly commandTemplate?: string;
|
|
26
33
|
readonly workspaceActionId?: string;
|
|
@@ -28,6 +35,27 @@ interface DelegationRoute {
|
|
|
28
35
|
readonly reviewPolicy?: 'explicit-only' | 'not-applicable';
|
|
29
36
|
}
|
|
30
37
|
|
|
38
|
+
type DelegationLaneId =
|
|
39
|
+
| 'local-first'
|
|
40
|
+
| 'tui-shared-session'
|
|
41
|
+
| 'delegated-review'
|
|
42
|
+
| 'remote-runner'
|
|
43
|
+
| 'hidden-fanout-blocked';
|
|
44
|
+
|
|
45
|
+
interface DelegationDecisionCard {
|
|
46
|
+
readonly id: string;
|
|
47
|
+
readonly lane: DelegationLaneId;
|
|
48
|
+
readonly label: string;
|
|
49
|
+
readonly status: 'ready' | 'operator-needed' | 'blocked';
|
|
50
|
+
readonly userBenefit: string;
|
|
51
|
+
readonly chooseWhen: readonly string[];
|
|
52
|
+
readonly doNotUseWhen: readonly string[];
|
|
53
|
+
readonly routeIds: readonly string[];
|
|
54
|
+
readonly requiredFields: readonly string[];
|
|
55
|
+
readonly supervision: readonly string[];
|
|
56
|
+
readonly confirmationBoundary: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
31
59
|
function readString(value: unknown): string {
|
|
32
60
|
return typeof value === 'string' ? value.trim() : '';
|
|
33
61
|
}
|
|
@@ -52,8 +80,20 @@ function routes(): readonly DelegationRoute[] {
|
|
|
52
80
|
{
|
|
53
81
|
id: 'delegate-build-task',
|
|
54
82
|
label: 'Delegate build/fix/review task',
|
|
55
|
-
detail: 'Send one explicit build, fix, implementation, patch, or review task to GoodVibes TUI/shared-session routes
|
|
83
|
+
detail: 'Send one explicit build, fix, implementation, patch, or review task to GoodVibes TUI/shared-session routes when isolation, remote execution, parallelism, a separate coding UI, or user-requested handoff is useful.',
|
|
56
84
|
effect: 'delegated-work',
|
|
85
|
+
lane: 'tui-shared-session',
|
|
86
|
+
bestFor: [
|
|
87
|
+
'Separate coding UI',
|
|
88
|
+
'Isolation or separate worktree ownership',
|
|
89
|
+
'Remote execution handled by the GoodVibes host or TUI',
|
|
90
|
+
'Parallel implementation or verification that should not block the main Agent conversation',
|
|
91
|
+
],
|
|
92
|
+
requiredFields: ['full original user ask', 'delegation reason', 'success criteria or expected evidence'],
|
|
93
|
+
optionalFields: ['workspace/worktree hint', 'deadline/priority', 'review requested yes/no'],
|
|
94
|
+
successEvidence: ['delegation receipt/session id', 'status update', 'diff or artifact summary', 'verification result when available'],
|
|
95
|
+
statusRoutes: ['/delegate status', '/health remote', 'delegation action:"status"'],
|
|
96
|
+
recoveryRoutes: ['Open GoodVibes TUI shared session', 'Use local Agent read/edit/exec when the current workspace is sufficient'],
|
|
57
97
|
commandTemplate: '/delegate <full original user ask>',
|
|
58
98
|
workspaceActionId: 'delegate-task',
|
|
59
99
|
confirmationRequired: true,
|
|
@@ -62,8 +102,19 @@ function routes(): readonly DelegationRoute[] {
|
|
|
62
102
|
{
|
|
63
103
|
id: 'delegate-build-task-with-review',
|
|
64
104
|
label: 'Delegate with requested review',
|
|
65
|
-
detail: 'Request delegated review only when the user explicitly asks for review or explicitly requests review as part of
|
|
105
|
+
detail: 'Request delegated review only when the user explicitly asks for review or explicitly requests review as part of an isolated or remote build/fix/review handoff.',
|
|
66
106
|
effect: 'delegated-work',
|
|
107
|
+
lane: 'delegated-review',
|
|
108
|
+
bestFor: [
|
|
109
|
+
'User explicitly asks for code review',
|
|
110
|
+
'Implementation handoff needs an independent review owner',
|
|
111
|
+
'Risky change needs WRFC-style evidence before merge/apply decisions',
|
|
112
|
+
],
|
|
113
|
+
requiredFields: ['full original user ask', 'explicit review request', 'review focus', 'success criteria or expected evidence'],
|
|
114
|
+
optionalFields: ['files/components in scope', 'known risks', 'deadline/priority'],
|
|
115
|
+
successEvidence: ['review receipt/session id', 'findings or approval summary', 'artifact/diff references', 'follow-up questions when blocked'],
|
|
116
|
+
statusRoutes: ['/delegate status', '/health remote', 'delegation action:"route" delegationRouteId:"delegate-build-task-with-review"'],
|
|
117
|
+
recoveryRoutes: ['Use local Agent review when the current workspace is sufficient', 'Open GoodVibes TUI shared session for review follow-up'],
|
|
67
118
|
commandTemplate: '/delegate --review <full original user ask>',
|
|
68
119
|
workspaceActionId: 'delegate-task',
|
|
69
120
|
confirmationRequired: true,
|
|
@@ -74,6 +125,13 @@ function routes(): readonly DelegationRoute[] {
|
|
|
74
125
|
label: 'Delegation status',
|
|
75
126
|
detail: 'Inspect build-delegation receipts and shared-session status without starting coding work.',
|
|
76
127
|
effect: 'read-only',
|
|
128
|
+
lane: 'tui-shared-session',
|
|
129
|
+
bestFor: ['Checking whether a delegated build/fix/review task was submitted', 'Finding the shared-session receipt before follow-up'],
|
|
130
|
+
requiredFields: [],
|
|
131
|
+
optionalFields: ['session id or task text when available'],
|
|
132
|
+
successEvidence: ['receipt/session id', 'latest shared-session status'],
|
|
133
|
+
statusRoutes: ['/delegate status'],
|
|
134
|
+
recoveryRoutes: ['/health remote', 'Open GoodVibes TUI in the target workspace'],
|
|
77
135
|
command: '/delegate status',
|
|
78
136
|
workspaceActionId: 'delegation-status',
|
|
79
137
|
reviewPolicy: 'not-applicable',
|
|
@@ -81,30 +139,178 @@ function routes(): readonly DelegationRoute[] {
|
|
|
81
139
|
{
|
|
82
140
|
id: 'ordinary-agent-work',
|
|
83
141
|
label: 'Ordinary Agent work',
|
|
84
|
-
detail: 'Planning, research, operations, memory, configuration, approvals, automation observability, media generation, and ordinary
|
|
142
|
+
detail: 'Planning, research, operations, memory, configuration, approvals, automation observability, media generation, and ordinary local read/edit/exec work stay in the main Agent conversation or first-class Agent tools.',
|
|
143
|
+
effect: 'main-conversation',
|
|
144
|
+
lane: 'local-first',
|
|
145
|
+
bestFor: ['Normal chat', 'Planning and research', 'Current-workspace implementation or verification with available local tools'],
|
|
146
|
+
requiredFields: [],
|
|
147
|
+
optionalFields: ['work plan item', 'verification command', 'user-visible success criteria'],
|
|
148
|
+
successEvidence: ['direct answer', 'local diff', 'test result', 'artifact id when an Agent tool saves one'],
|
|
149
|
+
statusRoutes: ['main conversation', 'execution action:"status"', 'execution action:"history"'],
|
|
150
|
+
recoveryRoutes: ['execution action:"recovery"', 'execution action:"route" id:"local-edit-write"'],
|
|
151
|
+
reviewPolicy: 'not-applicable',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: 'local-agent-execution',
|
|
155
|
+
label: 'Local Agent execution',
|
|
156
|
+
detail: 'Agent may use local read, edit, analyze, fetch, and bounded foreground shell tools when the current workspace and permissions are sufficient for the user request.',
|
|
85
157
|
effect: 'main-conversation',
|
|
158
|
+
lane: 'local-first',
|
|
159
|
+
bestFor: ['Current workspace code changes', 'Targeted tests/builds', 'Foreground command verification', 'Direct file recovery through Agent snapshots'],
|
|
160
|
+
requiredFields: ['user request or task objective'],
|
|
161
|
+
optionalFields: ['files/components in scope', 'verification command', 'risk notes'],
|
|
162
|
+
successEvidence: ['changed files', 'command/test output', 'execution history record', 'file recovery snapshot when edits were made'],
|
|
163
|
+
statusRoutes: ['execution action:"history"', 'execution action:"route" id:"local-shell-command"'],
|
|
164
|
+
recoveryRoutes: ['execution action:"recovery"', 'agent_harness mode:"run_file_recovery"'],
|
|
86
165
|
reviewPolicy: 'not-applicable',
|
|
87
166
|
},
|
|
88
167
|
{
|
|
89
|
-
id: '
|
|
90
|
-
label: '
|
|
91
|
-
detail: '
|
|
168
|
+
id: 'remote-runner-inspection',
|
|
169
|
+
label: 'Remote runner inspection',
|
|
170
|
+
detail: 'Inspect GoodVibes remote build-host pools, contracts, artifacts, and review summaries when the host exposes them; mutation-heavy remote pool assignment and artifact import are not Agent-owned actions.',
|
|
171
|
+
effect: 'read-only',
|
|
172
|
+
lane: 'remote-runner',
|
|
173
|
+
bestFor: ['Checking remote build-host health', 'Reviewing runner contracts', 'Reviewing remote artifacts that already exist'],
|
|
174
|
+
requiredFields: [],
|
|
175
|
+
optionalFields: ['runner id', 'artifact id', 'pool id'],
|
|
176
|
+
successEvidence: ['remote health summary', 'runner contract summary', 'remote artifact review summary'],
|
|
177
|
+
statusRoutes: ['/health remote', 'remote tool read-only modes: pools, contracts, artifacts, review'],
|
|
178
|
+
recoveryRoutes: ['Repair remote build-host state outside Agent', 'Use /delegate for build/fix/review execution changes'],
|
|
179
|
+
command: '/health remote',
|
|
180
|
+
reviewPolicy: 'not-applicable',
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: 'hidden-local-fanout-blocked',
|
|
184
|
+
label: 'Hidden local fanout blocked',
|
|
185
|
+
detail: 'Do not spawn invisible local coding workers, background exec batches, or untracked parallel subagents from Agent. Convert the request into local serial work, a visible work plan, a research run, an explicit schedule, or confirmed GoodVibes TUI/shared-session delegation.',
|
|
92
186
|
effect: 'blocked',
|
|
187
|
+
lane: 'hidden-fanout-blocked',
|
|
188
|
+
bestFor: ['Policy explanation when a request implies hidden background implementation work'],
|
|
189
|
+
requiredFields: [],
|
|
190
|
+
optionalFields: ['visible work-plan item', 'delegation reason', 'success criteria'],
|
|
191
|
+
successEvidence: ['chosen visible route', 'confirmation receipt when delegated'],
|
|
192
|
+
statusRoutes: ['execution action:"status"', 'autonomy action:"intake"'],
|
|
193
|
+
recoveryRoutes: ['delegation action:"status"', 'Agent Workspace -> Work plan'],
|
|
93
194
|
reviewPolicy: 'not-applicable',
|
|
94
195
|
},
|
|
95
196
|
];
|
|
96
197
|
}
|
|
97
198
|
|
|
199
|
+
export function delegationDecisionCards(context: CommandContext): readonly DelegationDecisionCard[] {
|
|
200
|
+
const operatorAttached = Boolean(context.clients?.operator);
|
|
201
|
+
return [
|
|
202
|
+
{
|
|
203
|
+
id: 'delegate-decision-local-first',
|
|
204
|
+
lane: 'local-first',
|
|
205
|
+
label: 'Keep it in Agent',
|
|
206
|
+
status: 'ready',
|
|
207
|
+
userBenefit: 'Fastest path for current-workspace work: no handoff, no duplicate context, direct verification and recovery.',
|
|
208
|
+
chooseWhen: [
|
|
209
|
+
'The current Agent workspace is the target.',
|
|
210
|
+
'Local read/edit/exec tools can complete and verify the work.',
|
|
211
|
+
'The user did not ask for a separate runner, worktree, or delegated review.',
|
|
212
|
+
],
|
|
213
|
+
doNotUseWhen: [
|
|
214
|
+
'The work needs a remote machine, separate worktree, independent review owner, or parallel execution lane.',
|
|
215
|
+
],
|
|
216
|
+
routeIds: ['ordinary-agent-work', 'local-agent-execution'],
|
|
217
|
+
requiredFields: ['task objective'],
|
|
218
|
+
supervision: ['execution action:"status"', 'execution action:"history"', 'execution action:"recovery"'],
|
|
219
|
+
confirmationBoundary: 'Use normal Agent tool confirmations; no shared-session delegation is submitted.',
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
id: 'delegate-decision-tui-handoff',
|
|
223
|
+
lane: 'tui-shared-session',
|
|
224
|
+
label: 'Delegate to GoodVibes TUI',
|
|
225
|
+
status: operatorAttached ? 'ready' : 'operator-needed',
|
|
226
|
+
userBenefit: 'Best route when the user benefits from the coding TUI, shared sessions, isolation, worktree ownership, or remote host workflows.',
|
|
227
|
+
chooseWhen: [
|
|
228
|
+
'The task is explicit build/fix/implementation/review work.',
|
|
229
|
+
'Delegation improves the user outcome versus staying local.',
|
|
230
|
+
'The full original ask, reason, and success criteria can be preserved.',
|
|
231
|
+
],
|
|
232
|
+
doNotUseWhen: [
|
|
233
|
+
'The task is ordinary local work that Agent can complete directly.',
|
|
234
|
+
'The user has not confirmed a mutating delegation submission.',
|
|
235
|
+
],
|
|
236
|
+
routeIds: ['delegate-build-task', 'delegation-status'],
|
|
237
|
+
requiredFields: ['full original user ask', 'delegation reason', 'success criteria or expected evidence'],
|
|
238
|
+
supervision: ['/delegate status', '/health remote', 'GoodVibes TUI shared session'],
|
|
239
|
+
confirmationBoundary: 'Submitting delegated work requires a confirmed workspace form or slash command and an attached operator client.',
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
id: 'delegate-decision-review',
|
|
243
|
+
lane: 'delegated-review',
|
|
244
|
+
label: 'Request delegated review',
|
|
245
|
+
status: operatorAttached ? 'ready' : 'operator-needed',
|
|
246
|
+
userBenefit: 'Adds an independent review owner only when the user explicitly asks for it or the handoff needs review as part of the task.',
|
|
247
|
+
chooseWhen: [
|
|
248
|
+
'The user asks for review, WRFC, second pass, or independent verification.',
|
|
249
|
+
'The delegated task has review focus and expected evidence.',
|
|
250
|
+
],
|
|
251
|
+
doNotUseWhen: [
|
|
252
|
+
'Review is only implied by the existence of a handoff.',
|
|
253
|
+
'A local code review in the current workspace is sufficient.',
|
|
254
|
+
],
|
|
255
|
+
routeIds: ['delegate-build-task-with-review', 'delegation-status'],
|
|
256
|
+
requiredFields: ['full original user ask', 'explicit review request', 'review focus', 'success criteria or expected evidence'],
|
|
257
|
+
supervision: ['/delegate status', 'GoodVibes TUI shared session'],
|
|
258
|
+
confirmationBoundary: 'The --review lane is explicit-only; Agent must not add review by default.',
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
id: 'delegate-decision-remote-inspect',
|
|
262
|
+
lane: 'remote-runner',
|
|
263
|
+
label: 'Inspect remote runners',
|
|
264
|
+
status: 'ready',
|
|
265
|
+
userBenefit: 'Keeps remote-host state understandable without exposing mutation-heavy pool or artifact operations through Agent.',
|
|
266
|
+
chooseWhen: [
|
|
267
|
+
'The user asks about remote build-host health, runner contracts, or existing remote artifacts.',
|
|
268
|
+
],
|
|
269
|
+
doNotUseWhen: [
|
|
270
|
+
'The user asks Agent to create pools, assign runners, import artifacts, or dispatch hidden remote work.',
|
|
271
|
+
],
|
|
272
|
+
routeIds: ['remote-runner-inspection'],
|
|
273
|
+
requiredFields: [],
|
|
274
|
+
supervision: ['/health remote', 'remote read-only tool modes: pools/contracts/artifacts/review'],
|
|
275
|
+
confirmationBoundary: 'Remote build-host mutation belongs outside Agent or through explicit GoodVibes TUI delegation.',
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
id: 'delegate-decision-hidden-fanout',
|
|
279
|
+
lane: 'hidden-fanout-blocked',
|
|
280
|
+
label: 'Block hidden fanout',
|
|
281
|
+
status: 'blocked',
|
|
282
|
+
userBenefit: 'Protects the user from invisible work, unclear ownership, unreviewed side effects, and orphaned background jobs.',
|
|
283
|
+
chooseWhen: [
|
|
284
|
+
'A request implies invisible local subagents, background exec batches, untracked remote dispatch, or unmanaged parallel coding workers.',
|
|
285
|
+
],
|
|
286
|
+
doNotUseWhen: [
|
|
287
|
+
'The work can be expressed as a visible work plan, research run, schedule, local serial tool use, or confirmed delegation.',
|
|
288
|
+
],
|
|
289
|
+
routeIds: ['hidden-local-fanout-blocked'],
|
|
290
|
+
requiredFields: [],
|
|
291
|
+
supervision: ['execution action:"status"', 'autonomy action:"intake"', 'work plan'],
|
|
292
|
+
confirmationBoundary: 'Hidden fanout is never confirmed from Agent; convert to a visible owned route.',
|
|
293
|
+
},
|
|
294
|
+
];
|
|
295
|
+
}
|
|
296
|
+
|
|
98
297
|
function routeSearchText(route: DelegationRoute): string {
|
|
99
298
|
return [
|
|
100
299
|
route.id,
|
|
101
300
|
route.label,
|
|
102
301
|
route.detail,
|
|
103
302
|
route.effect,
|
|
303
|
+
route.lane ?? '',
|
|
104
304
|
route.command ?? '',
|
|
105
305
|
route.commandTemplate ?? '',
|
|
106
306
|
route.workspaceActionId ?? '',
|
|
107
307
|
route.reviewPolicy ?? '',
|
|
308
|
+
...(route.bestFor ?? []),
|
|
309
|
+
...(route.requiredFields ?? []),
|
|
310
|
+
...(route.optionalFields ?? []),
|
|
311
|
+
...(route.successEvidence ?? []),
|
|
312
|
+
...(route.statusRoutes ?? []),
|
|
313
|
+
...(route.recoveryRoutes ?? []),
|
|
108
314
|
].join('\n').toLowerCase();
|
|
109
315
|
}
|
|
110
316
|
|
|
@@ -113,15 +319,14 @@ function describeCandidate(route: DelegationRoute): Record<string, unknown> {
|
|
|
113
319
|
delegationRouteId: route.id,
|
|
114
320
|
label: route.label,
|
|
115
321
|
effect: route.effect,
|
|
322
|
+
lane: route.lane ?? 'local-first',
|
|
116
323
|
confirmationRequired: route.confirmationRequired === true,
|
|
117
324
|
modelRoute: delegationRouteModelRoute(route),
|
|
118
325
|
};
|
|
119
326
|
}
|
|
120
327
|
|
|
121
328
|
function delegationRouteModelRoute(route: DelegationRoute): string {
|
|
122
|
-
|
|
123
|
-
if (route.command || route.commandTemplate) return 'agent_harness mode:"run_command"';
|
|
124
|
-
return route.effect === 'main-conversation' ? 'main conversation' : 'agent_harness mode:"delegation_route"';
|
|
329
|
+
return route.effect === 'main-conversation' ? 'main conversation' : `delegation action:"route" id:"${route.id}"`;
|
|
125
330
|
}
|
|
126
331
|
|
|
127
332
|
function describeRoute(
|
|
@@ -134,6 +339,7 @@ function describeRoute(
|
|
|
134
339
|
label: route.label,
|
|
135
340
|
...(options.includeParameters ? { detail: route.detail } : { summary: previewHarnessText(route.detail) }),
|
|
136
341
|
effect: route.effect,
|
|
342
|
+
lane: route.lane ?? 'local-first',
|
|
137
343
|
confirmationRequired: route.confirmationRequired === true,
|
|
138
344
|
reviewPolicy: route.reviewPolicy ?? 'not-applicable',
|
|
139
345
|
modelRoute: delegationRouteModelRoute(route),
|
|
@@ -145,6 +351,12 @@ function describeRoute(
|
|
|
145
351
|
...(route.command ? { command: route.command } : {}),
|
|
146
352
|
...(route.commandTemplate ? { commandTemplate: route.commandTemplate } : {}),
|
|
147
353
|
...(route.workspaceActionId ? { workspaceActionId: route.workspaceActionId } : {}),
|
|
354
|
+
bestFor: route.bestFor ?? [],
|
|
355
|
+
requiredFields: route.requiredFields ?? [],
|
|
356
|
+
optionalFields: route.optionalFields ?? [],
|
|
357
|
+
successEvidence: route.successEvidence ?? [],
|
|
358
|
+
statusRoutes: route.statusRoutes ?? [],
|
|
359
|
+
recoveryRoutes: route.recoveryRoutes ?? [],
|
|
148
360
|
} : {}),
|
|
149
361
|
...(options.lookup ? { lookup: options.lookup } : {}),
|
|
150
362
|
...(options.includeParameters ? {
|
|
@@ -154,12 +366,12 @@ function describeRoute(
|
|
|
154
366
|
mutation: 'Delegated work submission stays a visible confirmed workspace or slash-command flow and must preserve the full original user ask.',
|
|
155
367
|
},
|
|
156
368
|
modelAccess: {
|
|
157
|
-
inspectDelegation: '
|
|
158
|
-
inspectRoute: '
|
|
159
|
-
workspaceAction: route.workspaceActionId ? `
|
|
160
|
-
runWorkspaceAction: route.workspaceActionId ? `
|
|
161
|
-
runCommand: route.command ? `
|
|
162
|
-
runCommandTemplate: route.commandTemplate ? `
|
|
369
|
+
inspectDelegation: 'delegation action:"status"',
|
|
370
|
+
inspectRoute: 'delegation action:"route"',
|
|
371
|
+
workspaceAction: route.workspaceActionId ? `workspace action:"action" actionId:"${route.workspaceActionId}"` : null,
|
|
372
|
+
runWorkspaceAction: route.workspaceActionId ? `workspace action:"run" actionId:"${route.workspaceActionId}" confirm:true explicitUserRequest:"..."` : null,
|
|
373
|
+
runCommand: route.command ? `workspace action:"run_command" command:"${route.command}" confirm:true explicitUserRequest:"..."` : null,
|
|
374
|
+
runCommandTemplate: route.commandTemplate ? `workspace action:"run_command" command:"${route.commandTemplate}" confirm:true explicitUserRequest:"..."` : null,
|
|
163
375
|
},
|
|
164
376
|
} : {}),
|
|
165
377
|
};
|
|
@@ -169,6 +381,7 @@ export function delegationPostureCatalogStatus(context: CommandContext): Record<
|
|
|
169
381
|
return {
|
|
170
382
|
modes: ['delegation_posture', 'delegation_route'],
|
|
171
383
|
routes: routes().length,
|
|
384
|
+
decisionCards: delegationDecisionCards(context).length,
|
|
172
385
|
operatorClientAttached: Boolean(context.clients?.operator),
|
|
173
386
|
readOnly: true,
|
|
174
387
|
};
|
|
@@ -184,12 +397,14 @@ export function delegationPostureSummary(context: CommandContext, args: AgentHar
|
|
|
184
397
|
status: 'available',
|
|
185
398
|
summary: {
|
|
186
399
|
routes: routes().length,
|
|
400
|
+
decisionCards: delegationDecisionCards(context).length,
|
|
187
401
|
operatorClientAttached: Boolean(context.clients?.operator),
|
|
188
402
|
sessionId: context.session.runtime.sessionId,
|
|
189
403
|
delegatedReviewPolicy: 'explicit-build-delegation-only',
|
|
190
|
-
normalChatPolicy: 'ordinary assistant work
|
|
191
|
-
codingOwnership: 'GoodVibes TUI
|
|
404
|
+
normalChatPolicy: 'ordinary assistant work and suitable local execution stay in the main Agent conversation',
|
|
405
|
+
codingOwnership: 'Agent may use local read/edit/exec when the current workspace is sufficient; GoodVibes TUI/shared-session routes own isolation, remote execution, separate worktrees, coding panels, and delegated review coordination',
|
|
192
406
|
},
|
|
407
|
+
decisionCards: delegationDecisionCards(context),
|
|
193
408
|
routes: filtered.map((route) => describeRoute(context, route, { includeParameters })),
|
|
194
409
|
returned: filtered.length,
|
|
195
410
|
total: routes().length,
|
|
@@ -202,7 +417,7 @@ export function describeHarnessDelegationRoute(context: CommandContext, args: Ag
|
|
|
202
417
|
if (!lookup) {
|
|
203
418
|
return {
|
|
204
419
|
status: 'missing_lookup',
|
|
205
|
-
usage: '
|
|
420
|
+
usage: 'delegation action:"route" requires delegationRouteId, target, or query. Use delegation action:"status" to inspect delegation route ids.',
|
|
206
421
|
};
|
|
207
422
|
}
|
|
208
423
|
const all = routes();
|
|
@@ -222,6 +437,6 @@ export function describeHarnessDelegationRoute(context: CommandContext, args: Ag
|
|
|
222
437
|
}
|
|
223
438
|
return {
|
|
224
439
|
status: 'missing_lookup',
|
|
225
|
-
usage: `Unknown delegation route ${lookup.input}. Use
|
|
440
|
+
usage: `Unknown delegation route ${lookup.input}. Use delegation action:"status" to inspect delegation route ids.`,
|
|
226
441
|
};
|
|
227
442
|
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import type { ArtifactDescriptor } from '@pellux/goodvibes-sdk/platform/artifacts';
|
|
2
|
+
import type { CommandContext } from '../input/command-registry.ts';
|
|
3
|
+
import { AgentDocumentRegistry, type AgentDocumentRecord } from '../agent/document-registry.ts';
|
|
4
|
+
import type { ReviewerReadinessCheck, ReviewerReadinessChecklist, ReviewerReadinessStatus } from './agent-harness-document-ops-types.ts';
|
|
5
|
+
|
|
6
|
+
function readMetadataString(value: unknown): string {
|
|
7
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function readMetadataStringList(value: unknown): readonly string[] {
|
|
11
|
+
if (typeof value === 'string') {
|
|
12
|
+
return value.split(/[,\n]/).map((entry) => entry.trim()).filter(Boolean);
|
|
13
|
+
}
|
|
14
|
+
if (!Array.isArray(value)) return [];
|
|
15
|
+
return value.filter((entry): entry is string => typeof entry === 'string').map((entry) => entry.trim()).filter(Boolean);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function artifactPurpose(artifact: ArtifactDescriptor): string {
|
|
19
|
+
return readMetadataString(artifact.metadata.purpose);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isModelCompareArtifact(artifact: ArtifactDescriptor): boolean {
|
|
23
|
+
const purpose = artifactPurpose(artifact);
|
|
24
|
+
if (purpose === 'agent-model-compare') return true;
|
|
25
|
+
if (purpose) return false;
|
|
26
|
+
return readMetadataString(artifact.filename).startsWith('blind-model-comparison-cmp_');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function isModelCompareJudgmentArtifact(artifact: ArtifactDescriptor): boolean {
|
|
30
|
+
const purpose = artifactPurpose(artifact);
|
|
31
|
+
if (purpose === 'agent-model-compare-judgment') return true;
|
|
32
|
+
if (purpose) return false;
|
|
33
|
+
return readMetadataString(artifact.filename).startsWith('blind-model-comparison-judgment-');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isModelCompareRouteDecisionArtifact(artifact: ArtifactDescriptor): boolean {
|
|
37
|
+
return artifactPurpose(artifact) === 'agent-model-compare-route-decision';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isModelCompareHandoffArtifact(artifact: ArtifactDescriptor): boolean {
|
|
41
|
+
const purpose = artifactPurpose(artifact);
|
|
42
|
+
if (purpose === 'agent-model-compare-handoff') return true;
|
|
43
|
+
if (purpose) return false;
|
|
44
|
+
return readMetadataString(artifact.filename).startsWith('blind-model-comparison-handoff-');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readDocuments(context: CommandContext): readonly AgentDocumentRecord[] {
|
|
48
|
+
const shellPaths = context.workspace?.shellPaths;
|
|
49
|
+
if (!shellPaths) return [];
|
|
50
|
+
try {
|
|
51
|
+
return AgentDocumentRegistry.fromShellPaths(shellPaths).list();
|
|
52
|
+
} catch {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function readArtifacts(context: CommandContext): readonly ArtifactDescriptor[] {
|
|
58
|
+
try {
|
|
59
|
+
return context.platform.artifactStore?.list?.(100) ?? [];
|
|
60
|
+
} catch {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function reviewerReadinessStatus(checks: readonly ReviewerReadinessCheck[]): ReviewerReadinessStatus {
|
|
66
|
+
if (checks.some((check) => check.status === 'needs-setup')) return 'needs-setup';
|
|
67
|
+
if (checks.some((check) => check.status === 'attention')) return 'attention';
|
|
68
|
+
return 'ready';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function buildReviewerReadinessChecklist(
|
|
72
|
+
context: CommandContext,
|
|
73
|
+
options: {
|
|
74
|
+
readonly documentsReady: boolean;
|
|
75
|
+
readonly modelCompareReady: boolean;
|
|
76
|
+
readonly artifactBrowserReady: boolean;
|
|
77
|
+
},
|
|
78
|
+
): ReviewerReadinessChecklist {
|
|
79
|
+
const documents = readDocuments(context);
|
|
80
|
+
const reviewDocuments = documents.filter((document) => document.status !== 'archived');
|
|
81
|
+
const openComments = reviewDocuments.reduce((total, document) => total + document.comments.filter((comment) => comment.status === 'open').length, 0);
|
|
82
|
+
const proposedSuggestions = reviewDocuments.reduce((total, document) => total + document.suggestions.filter((suggestion) => suggestion.status === 'proposed').length, 0);
|
|
83
|
+
const documentsMissingSourceArtifacts = reviewDocuments.filter((document) => document.attachments.length === 0 && !document.lastArtifactId).length;
|
|
84
|
+
const artifacts = readArtifacts(context);
|
|
85
|
+
const comparisons = artifacts.filter(isModelCompareArtifact);
|
|
86
|
+
const judgments = artifacts.filter(isModelCompareJudgmentArtifact);
|
|
87
|
+
const routeDecisions = artifacts.filter(isModelCompareRouteDecisionArtifact);
|
|
88
|
+
const handoffs = artifacts.filter(isModelCompareHandoffArtifact);
|
|
89
|
+
const revealedJudgments = judgments.filter((artifact) => (
|
|
90
|
+
artifact.metadata.revealIncludedInJudgment === true
|
|
91
|
+
&& readMetadataString(artifact.metadata.winnerModel).length > 0
|
|
92
|
+
));
|
|
93
|
+
const hiddenJudgments = judgments.filter((artifact) => (
|
|
94
|
+
artifact.metadata.revealIncludedInJudgment !== true
|
|
95
|
+
|| readMetadataString(artifact.metadata.winnerModel).length === 0
|
|
96
|
+
));
|
|
97
|
+
const routeDecisionComparisonIds = new Set(routeDecisions.map((artifact) => readMetadataString(artifact.metadata.comparisonId)).filter(Boolean));
|
|
98
|
+
const routeDecisionJudgmentArtifactIds = new Set(routeDecisions.map((artifact) => readMetadataString(artifact.metadata.judgmentArtifactId)).filter(Boolean));
|
|
99
|
+
const revealedJudgmentsWaitingOnRouteDecision = revealedJudgments.filter((artifact) => {
|
|
100
|
+
const comparisonId = readMetadataString(artifact.metadata.comparisonId);
|
|
101
|
+
return !routeDecisionJudgmentArtifactIds.has(artifact.id) && (!comparisonId || !routeDecisionComparisonIds.has(comparisonId));
|
|
102
|
+
});
|
|
103
|
+
const revealedComparisonIds = new Set(revealedJudgments.map((artifact) => readMetadataString(artifact.metadata.comparisonId)).filter(Boolean));
|
|
104
|
+
const unrevealedComparisons = comparisons.filter((artifact) => {
|
|
105
|
+
const comparisonId = readMetadataString(artifact.metadata.comparisonId);
|
|
106
|
+
return artifact.metadata.revealIncludedInTranscript !== true && (!comparisonId || !revealedComparisonIds.has(comparisonId));
|
|
107
|
+
});
|
|
108
|
+
const handoffsMissingRelatedArtifacts = handoffs.filter((artifact) => readMetadataStringList(artifact.metadata.relatedArtifactIds).length === 0).length;
|
|
109
|
+
const comparisonSourceMissing = comparisons.filter((artifact) => (
|
|
110
|
+
!readMetadataString(artifact.metadata.sourceArtifactId)
|
|
111
|
+
&& !readMetadataString(artifact.metadata.documentId)
|
|
112
|
+
)).length;
|
|
113
|
+
const missingSourceArtifacts = documentsMissingSourceArtifacts + comparisonSourceMissing;
|
|
114
|
+
const firstOpenCommentDocument = reviewDocuments.find((document) => document.comments.some((comment) => comment.status === 'open'));
|
|
115
|
+
const firstProposedSuggestionDocument = reviewDocuments.find((document) => document.suggestions.some((suggestion) => suggestion.status === 'proposed'));
|
|
116
|
+
const firstUnrevealedComparison = unrevealedComparisons[0];
|
|
117
|
+
const firstHiddenJudgment = hiddenJudgments[0];
|
|
118
|
+
const firstRevealedJudgment = revealedJudgmentsWaitingOnRouteDecision[0];
|
|
119
|
+
const firstHandoffMissingRelated = handoffs.find((artifact) => readMetadataStringList(artifact.metadata.relatedArtifactIds).length === 0);
|
|
120
|
+
|
|
121
|
+
const checks: ReviewerReadinessCheck[] = [
|
|
122
|
+
{
|
|
123
|
+
id: 'review-tooling',
|
|
124
|
+
label: 'Review tooling',
|
|
125
|
+
status: options.documentsReady && options.modelCompareReady && options.artifactBrowserReady ? 'pass' : 'needs-setup',
|
|
126
|
+
count: Number(options.documentsReady) + Number(options.modelCompareReady) + Number(options.artifactBrowserReady),
|
|
127
|
+
detail: options.documentsReady && options.modelCompareReady && options.artifactBrowserReady
|
|
128
|
+
? 'Document, artifact, and blind comparison routes are available.'
|
|
129
|
+
: 'Document, artifact, and blind comparison routes must be available before a reviewer-ready export can be trusted.',
|
|
130
|
+
inspectRoute: 'agent_harness mode:"document_ops"',
|
|
131
|
+
repairRoute: 'agent_harness mode:"workspace_actions" categoryId:"documents"',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'document-review-state',
|
|
135
|
+
label: 'Document comments and suggestions',
|
|
136
|
+
status: openComments + proposedSuggestions > 0 ? 'attention' : 'pass',
|
|
137
|
+
count: openComments + proposedSuggestions,
|
|
138
|
+
detail: openComments + proposedSuggestions > 0
|
|
139
|
+
? `${openComments} open comment(s) and ${proposedSuggestions} proposed suggestion(s) need a visible resolve, accept, or reject decision.`
|
|
140
|
+
: 'No open document comments or proposed AI suggestions are waiting on reviewer action.',
|
|
141
|
+
inspectRoute: firstOpenCommentDocument || firstProposedSuggestionDocument
|
|
142
|
+
? `agent_documents show documentId:"${firstOpenCommentDocument?.id ?? firstProposedSuggestionDocument?.id}" includeVersions:true`
|
|
143
|
+
: 'agent_documents list',
|
|
144
|
+
repairRoute: firstOpenCommentDocument
|
|
145
|
+
? `agent_documents resolveComment documentId:"${firstOpenCommentDocument.id}" commentId:"..." confirm:true explicitUserRequest:"..."`
|
|
146
|
+
: firstProposedSuggestionDocument
|
|
147
|
+
? `agent_documents acceptSuggestion documentId:"${firstProposedSuggestionDocument.id}" suggestionId:"..." confirm:true explicitUserRequest:"..." or agent_documents rejectSuggestion documentId:"${firstProposedSuggestionDocument.id}" suggestionId:"..." confirm:true explicitUserRequest:"..."`
|
|
148
|
+
: undefined,
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: 'source-artifacts',
|
|
152
|
+
label: 'Source artifacts',
|
|
153
|
+
status: missingSourceArtifacts > 0 ? 'attention' : 'pass',
|
|
154
|
+
count: missingSourceArtifacts,
|
|
155
|
+
detail: missingSourceArtifacts > 0
|
|
156
|
+
? `${documentsMissingSourceArtifacts} document draft(s) and ${comparisonSourceMissing} comparison artifact(s) have no attached source artifact or document source marker.`
|
|
157
|
+
: 'Document drafts and saved comparisons have source artifacts or explicit document/source markers where the current stores can verify them.',
|
|
158
|
+
inspectRoute: 'agent_harness mode:"document_ops_lane" laneId:"artifact_browser"',
|
|
159
|
+
repairRoute: missingSourceArtifacts > 0
|
|
160
|
+
? 'agent_documents attachArtifact documentId:"..." artifactId:"..." confirm:true explicitUserRequest:"..." or agent_model_compare handoff artifactId:"..." relatedArtifactIds:"..." confirm:true explicitUserRequest:"..."'
|
|
161
|
+
: undefined,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: 'comparison-reveal',
|
|
165
|
+
label: 'Blind comparison reveal',
|
|
166
|
+
status: unrevealedComparisons.length + hiddenJudgments.length > 0 ? 'attention' : 'pass',
|
|
167
|
+
count: unrevealedComparisons.length + hiddenJudgments.length,
|
|
168
|
+
detail: unrevealedComparisons.length + hiddenJudgments.length > 0
|
|
169
|
+
? `${unrevealedComparisons.length} saved comparison(s) and ${hiddenJudgments.length} judgment(s) still hide winner identity before reviewer handoff.`
|
|
170
|
+
: 'Saved comparison judgments with route-change implications are revealed, or no hidden comparison artifacts are pending.',
|
|
171
|
+
inspectRoute: firstUnrevealedComparison
|
|
172
|
+
? `agent_model_compare review artifactId:"${firstUnrevealedComparison.id}"`
|
|
173
|
+
: firstHiddenJudgment
|
|
174
|
+
? `agent_model_compare review artifactId:"${firstHiddenJudgment.id}"`
|
|
175
|
+
: 'agent_model_compare review',
|
|
176
|
+
repairRoute: firstUnrevealedComparison
|
|
177
|
+
? `agent_model_compare reveal artifactId:"${firstUnrevealedComparison.id}"`
|
|
178
|
+
: firstHiddenJudgment
|
|
179
|
+
? `agent_model_compare judge artifactId:"${readMetadataString(firstHiddenJudgment.metadata.sourceArtifactId) || firstHiddenJudgment.id}" winnerBlindId:"${readMetadataString(firstHiddenJudgment.metadata.winnerBlindId) || '...'}" reveal:true confirm:true explicitUserRequest:"..."`
|
|
180
|
+
: undefined,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: 'route-change-decision',
|
|
184
|
+
label: 'Route-change decision',
|
|
185
|
+
status: revealedJudgmentsWaitingOnRouteDecision.length > 0 ? 'attention' : 'pass',
|
|
186
|
+
count: revealedJudgmentsWaitingOnRouteDecision.length,
|
|
187
|
+
detail: revealedJudgmentsWaitingOnRouteDecision.length > 0
|
|
188
|
+
? `${revealedJudgmentsWaitingOnRouteDecision.length} revealed judgment(s) can drive a confirmed model route update, or the user can explicitly leave routing unchanged before archiving.`
|
|
189
|
+
: 'No revealed model comparison judgment is waiting on an apply-or-leave-unchanged decision.',
|
|
190
|
+
inspectRoute: firstRevealedJudgment
|
|
191
|
+
? `agent_model_compare review artifactId:"${firstRevealedJudgment.id}" reveal:true`
|
|
192
|
+
: 'models action:"status"',
|
|
193
|
+
repairRoute: firstRevealedJudgment
|
|
194
|
+
? `agent_model_compare apply artifactId:"${firstRevealedJudgment.id}" confirm:true explicitUserRequest:"..." or agent_model_compare routeDecision artifactId:"${firstRevealedJudgment.id}" decision:"left-unchanged" confirm:true explicitUserRequest:"..."`
|
|
195
|
+
: undefined,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: 'handoff-archive-evidence',
|
|
199
|
+
label: 'Reviewer handoff evidence',
|
|
200
|
+
status: handoffsMissingRelatedArtifacts > 0 ? 'attention' : 'pass',
|
|
201
|
+
count: handoffsMissingRelatedArtifacts,
|
|
202
|
+
detail: handoffsMissingRelatedArtifacts > 0
|
|
203
|
+
? `${handoffsMissingRelatedArtifacts} reviewer handoff artifact(s) have no related evidence artifact ids before archive.`
|
|
204
|
+
: 'Reviewer handoff artifacts include related evidence ids, or no reviewer handoff archive is pending.',
|
|
205
|
+
inspectRoute: firstHandoffMissingRelated
|
|
206
|
+
? `agent_model_compare review artifactId:"${firstHandoffMissingRelated.id}"`
|
|
207
|
+
: 'agent_model_compare review',
|
|
208
|
+
repairRoute: firstHandoffMissingRelated
|
|
209
|
+
? `agent_model_compare handoff artifactId:"${readMetadataString(firstHandoffMissingRelated.metadata.sourceArtifactId) || firstHandoffMissingRelated.id}" relatedArtifactIds:"..." confirm:true explicitUserRequest:"..."`
|
|
210
|
+
: undefined,
|
|
211
|
+
},
|
|
212
|
+
];
|
|
213
|
+
const status = reviewerReadinessStatus(checks);
|
|
214
|
+
const firstAction = checks.find((check) => check.status === 'attention' || check.status === 'needs-setup');
|
|
215
|
+
return {
|
|
216
|
+
status,
|
|
217
|
+
next: firstAction
|
|
218
|
+
? `${firstAction.label}: ${firstAction.detail}`
|
|
219
|
+
: 'Export or archive reviewer packets through the returned confirmed document, artifact, or comparison routes.',
|
|
220
|
+
summary: {
|
|
221
|
+
documents: documents.length,
|
|
222
|
+
openComments,
|
|
223
|
+
proposedSuggestions,
|
|
224
|
+
documentsMissingSourceArtifacts,
|
|
225
|
+
savedComparisons: comparisons.length,
|
|
226
|
+
unrevealedComparisons: unrevealedComparisons.length,
|
|
227
|
+
hiddenJudgments: hiddenJudgments.length,
|
|
228
|
+
revealedJudgments: revealedJudgmentsWaitingOnRouteDecision.length,
|
|
229
|
+
handoffsMissingRelatedArtifacts,
|
|
230
|
+
},
|
|
231
|
+
checks,
|
|
232
|
+
policy: 'Reviewer readiness is read-only. It flags unresolved review work and returns exact existing routes; document exports, comparison handoffs, archives, and model route updates still require explicit confirmation.',
|
|
233
|
+
};
|
|
234
|
+
}
|