@resolveio/server-lib 22.3.142 → 22.3.144
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/ai/assistant-core-heuristics.d.ts +11 -0
- package/ai/assistant-core-heuristics.js +356 -0
- package/ai/assistant-core-heuristics.js.map +1 -0
- package/ai/resolveio-platform-intelligence-memory-corpus.d.ts +3 -0
- package/ai/resolveio-platform-intelligence-memory-corpus.js +214 -0
- package/ai/resolveio-platform-intelligence-memory-corpus.js.map +1 -0
- package/ai/resolveio-platform-intelligence-memory.d.ts +20 -0
- package/ai/resolveio-platform-intelligence-memory.js +341 -0
- package/ai/resolveio-platform-intelligence-memory.js.map +1 -0
- package/{src/ai/resolveio-platform-intelligence-types.ts → ai/resolveio-platform-intelligence-types.d.ts} +15 -20
- package/ai/resolveio-platform-intelligence-types.js +4 -0
- package/ai/resolveio-platform-intelligence-types.js.map +1 -0
- package/ai/resolveio-platform-intelligence.d.ts +6 -0
- package/ai/resolveio-platform-intelligence.js +463 -0
- package/ai/resolveio-platform-intelligence.js.map +1 -0
- package/client-server-app.d.ts +1 -0
- package/client-server-app.js +68 -0
- package/client-server-app.js.map +1 -0
- package/collections/ai-run.collection.d.ts +3 -0
- package/collections/ai-run.collection.js +170 -0
- package/collections/ai-run.collection.js.map +1 -0
- package/collections/ai-terminal-conversation.collection.d.ts +2 -0
- package/collections/ai-terminal-conversation.collection.js +140 -0
- package/collections/ai-terminal-conversation.collection.js.map +1 -0
- package/collections/ai-terminal-issue-report.collection.d.ts +2 -0
- package/collections/ai-terminal-issue-report.collection.js +148 -0
- package/collections/ai-terminal-issue-report.collection.js.map +1 -0
- package/collections/ai-terminal-message.collection.d.ts +2 -0
- package/collections/ai-terminal-message.collection.js +121 -0
- package/collections/ai-terminal-message.collection.js.map +1 -0
- package/collections/app-setting.collection.d.ts +3 -0
- package/collections/app-setting.collection.js +103 -0
- package/collections/app-setting.collection.js.map +1 -0
- package/collections/app-status.collection.d.ts +3 -0
- package/collections/app-status.collection.js +57 -0
- package/collections/app-status.collection.js.map +1 -0
- package/collections/communication-metric.collection.d.ts +2 -0
- package/collections/communication-metric.collection.js +133 -0
- package/collections/communication-metric.collection.js.map +1 -0
- package/collections/counter.collection.d.ts +3 -0
- package/collections/counter.collection.js +56 -0
- package/collections/counter.collection.js.map +1 -0
- package/collections/cron-job-history.collection.d.ts +3 -0
- package/collections/cron-job-history.collection.js +137 -0
- package/collections/cron-job-history.collection.js.map +1 -0
- package/collections/cron-job.collection.d.ts +3 -0
- package/collections/cron-job.collection.js +92 -0
- package/collections/cron-job.collection.js.map +1 -0
- package/collections/customer-notification.collection.d.ts +3 -0
- package/collections/customer-notification.collection.js +130 -0
- package/collections/customer-notification.collection.js.map +1 -0
- package/collections/customer-portal-password.collection.d.ts +3 -0
- package/collections/customer-portal-password.collection.js +75 -0
- package/collections/customer-portal-password.collection.js.map +1 -0
- package/collections/email-history.collection.d.ts +3 -0
- package/collections/email-history.collection.js +134 -0
- package/collections/email-history.collection.js.map +1 -0
- package/collections/email-verified.collection.d.ts +3 -0
- package/collections/email-verified.collection.js +62 -0
- package/collections/email-verified.collection.js.map +1 -0
- package/collections/file.collection.d.ts +3 -0
- package/collections/file.collection.js +74 -0
- package/collections/file.collection.js.map +1 -0
- package/collections/flag-update.collection.d.ts +3 -0
- package/collections/flag-update.collection.js +57 -0
- package/collections/flag-update.collection.js.map +1 -0
- package/collections/flag.collection.d.ts +3 -0
- package/collections/flag.collection.js +57 -0
- package/collections/flag.collection.js.map +1 -0
- package/collections/log-method-latency.collection.d.ts +3 -0
- package/collections/log-method-latency.collection.js +77 -0
- package/collections/log-method-latency.collection.js.map +1 -0
- package/collections/log-subscription.collection.d.ts +3 -0
- package/collections/log-subscription.collection.js +80 -0
- package/collections/log-subscription.collection.js.map +1 -0
- package/collections/log.collection.d.ts +3 -0
- package/collections/log.collection.js +93 -0
- package/collections/log.collection.js.map +1 -0
- package/collections/logged-in-users.collection.d.ts +3 -0
- package/collections/logged-in-users.collection.js +67 -0
- package/collections/logged-in-users.collection.js.map +1 -0
- package/collections/monitor-cpu.collection.d.ts +3 -0
- package/collections/monitor-cpu.collection.js +65 -0
- package/collections/monitor-cpu.collection.js.map +1 -0
- package/collections/monitor-function.collection.d.ts +3 -0
- package/collections/monitor-function.collection.js +74 -0
- package/collections/monitor-function.collection.js.map +1 -0
- package/collections/monitor-memory.collection.d.ts +3 -0
- package/collections/monitor-memory.collection.js +77 -0
- package/collections/monitor-memory.collection.js.map +1 -0
- package/collections/monitor-mongo.collection.d.ts +3 -0
- package/collections/monitor-mongo.collection.js +71 -0
- package/collections/monitor-mongo.collection.js.map +1 -0
- package/collections/notification.collection.d.ts +3 -0
- package/collections/notification.collection.js +57 -0
- package/collections/notification.collection.js.map +1 -0
- package/collections/openai-usage-ledger.collection.d.ts +2 -0
- package/collections/openai-usage-ledger.collection.js +124 -0
- package/collections/openai-usage-ledger.collection.js.map +1 -0
- package/collections/report-builder-dashboard-builder.collection.d.ts +3 -0
- package/collections/report-builder-dashboard-builder.collection.js +109 -0
- package/collections/report-builder-dashboard-builder.collection.js.map +1 -0
- package/collections/report-builder-library.collection.d.ts +3 -0
- package/collections/report-builder-library.collection.js +87 -0
- package/collections/report-builder-library.collection.js.map +1 -0
- package/collections/report-builder-report.collection.d.ts +4 -0
- package/collections/report-builder-report.collection.js +184 -0
- package/collections/report-builder-report.collection.js.map +1 -0
- package/collections/user-group.collection.d.ts +4 -0
- package/collections/user-group.collection.js +89 -0
- package/collections/user-group.collection.js.map +1 -0
- package/collections/user-guide.collection.d.ts +3 -0
- package/collections/user-guide.collection.js +57 -0
- package/collections/user-guide.collection.js.map +1 -0
- package/collections/user.collection.d.ts +4 -0
- package/collections/user.collection.js +180 -0
- package/collections/user.collection.js.map +1 -0
- package/cron/cron.d.ts +14 -0
- package/cron/cron.js +216 -0
- package/cron/cron.js.map +1 -0
- package/fixtures/cron-jobs.d.ts +1 -0
- package/fixtures/cron-jobs.js +150 -0
- package/fixtures/cron-jobs.js.map +1 -0
- package/fixtures/init.d.ts +1 -0
- package/fixtures/init.js +91 -0
- package/fixtures/init.js.map +1 -0
- package/http/auth.d.ts +2 -0
- package/http/auth.js +951 -0
- package/http/auth.js.map +1 -0
- package/http/health.d.ts +1 -0
- package/http/health.js +11 -0
- package/http/health.js.map +1 -0
- package/http/home.d.ts +1 -0
- package/http/home.js +134 -0
- package/http/home.js.map +1 -0
- package/http/slow-query-publication.d.ts +2 -0
- package/http/slow-query-publication.js +99 -0
- package/http/slow-query-publication.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +19 -0
- package/index.js.map +1 -0
- package/managers/ai-assistant-codex-manager.manager.d.ts +67 -0
- package/managers/ai-assistant-codex-manager.manager.js +1113 -0
- package/managers/ai-assistant-codex-manager.manager.js.map +1 -0
- package/managers/ai-run-evidence.manager.d.ts +36 -0
- package/managers/ai-run-evidence.manager.js +377 -0
- package/managers/ai-run-evidence.manager.js.map +1 -0
- package/managers/communication-metric.manager.d.ts +16 -0
- package/managers/communication-metric.manager.js +134 -0
- package/managers/communication-metric.manager.js.map +1 -0
- package/managers/cron.manager.d.ts +20 -0
- package/managers/cron.manager.js +534 -0
- package/managers/cron.manager.js.map +1 -0
- package/managers/customer-notification-content.manager.d.ts +55 -0
- package/managers/customer-notification-content.manager.js +158 -0
- package/managers/customer-notification-content.manager.js.map +1 -0
- package/managers/diagnostic-manager-bootstrap.d.ts +9 -0
- package/managers/diagnostic-manager-bootstrap.js +260 -0
- package/managers/diagnostic-manager-bootstrap.js.map +1 -0
- package/managers/error-auto-fix.manager.d.ts +149 -0
- package/managers/error-auto-fix.manager.js +3064 -0
- package/managers/error-auto-fix.manager.js.map +1 -0
- package/managers/local-log.manager.d.ts +18 -0
- package/managers/local-log.manager.js +88 -0
- package/managers/local-log.manager.js.map +1 -0
- package/managers/method.manager.d.ts +84 -0
- package/managers/method.manager.js +1964 -0
- package/managers/method.manager.js.map +1 -0
- package/managers/mongo.manager.d.ts +224 -0
- package/managers/mongo.manager.js +5000 -0
- package/managers/mongo.manager.js.map +1 -0
- package/managers/monitor.manager.d.ts +70 -0
- package/managers/monitor.manager.js +550 -0
- package/managers/monitor.manager.js.map +1 -0
- package/managers/openai-usage-ledger.manager.d.ts +16 -0
- package/managers/openai-usage-ledger.manager.js +93 -0
- package/managers/openai-usage-ledger.manager.js.map +1 -0
- package/managers/slow-query-verifier.manager.d.ts +144 -0
- package/managers/slow-query-verifier.manager.js +3857 -0
- package/managers/slow-query-verifier.manager.js.map +1 -0
- package/managers/slow-query.manager.d.ts +28 -0
- package/managers/slow-query.manager.js +468 -0
- package/managers/slow-query.manager.js.map +1 -0
- package/managers/subscription.manager.d.ts +169 -0
- package/managers/subscription.manager.js +3434 -0
- package/managers/subscription.manager.js.map +1 -0
- package/managers/websocket.manager.d.ts +73 -0
- package/managers/websocket.manager.js +673 -0
- package/managers/websocket.manager.js.map +1 -0
- package/managers/worker-dispatcher.manager.d.ts +120 -0
- package/managers/worker-dispatcher.manager.js +1266 -0
- package/managers/worker-dispatcher.manager.js.map +1 -0
- package/managers/worker-server.manager.d.ts +35 -0
- package/managers/worker-server.manager.js +582 -0
- package/managers/worker-server.manager.js.map +1 -0
- package/methods/accounts.d.ts +2 -0
- package/methods/accounts.js +624 -0
- package/methods/accounts.js.map +1 -0
- package/methods/ai-terminal.d.ts +337 -0
- package/methods/ai-terminal.js +23166 -0
- package/methods/ai-terminal.js.map +1 -0
- package/methods/app-settings.d.ts +2 -0
- package/methods/app-settings.js +169 -0
- package/methods/app-settings.js.map +1 -0
- package/methods/aws.d.ts +2 -0
- package/methods/aws.js +877 -0
- package/methods/aws.js.map +1 -0
- package/methods/collections.d.ts +2 -0
- package/methods/collections.js +719 -0
- package/methods/collections.js.map +1 -0
- package/methods/counters.d.ts +2 -0
- package/methods/counters.js +113 -0
- package/methods/counters.js.map +1 -0
- package/methods/cron-jobs.d.ts +2 -0
- package/methods/cron-jobs.js +2475 -0
- package/methods/cron-jobs.js.map +1 -0
- package/methods/customer-notifications.d.ts +2 -0
- package/methods/customer-notifications.js +528 -0
- package/methods/customer-notifications.js.map +1 -0
- package/methods/diagnostics.d.ts +2 -0
- package/methods/diagnostics.js +703 -0
- package/methods/diagnostics.js.map +1 -0
- package/methods/flag-updates.d.ts +2 -0
- package/methods/flag-updates.js +8 -0
- package/methods/flag-updates.js.map +1 -0
- package/methods/flags.d.ts +2 -0
- package/methods/flags.js +8 -0
- package/methods/flags.js.map +1 -0
- package/methods/logs.d.ts +2 -0
- package/methods/logs.js +751 -0
- package/methods/logs.js.map +1 -0
- package/methods/mongo-explorer.d.ts +2 -0
- package/methods/mongo-explorer.js +1808 -0
- package/methods/mongo-explorer.js.map +1 -0
- package/methods/monitor.d.ts +2 -0
- package/methods/monitor.js +543 -0
- package/methods/monitor.js.map +1 -0
- package/methods/pdf.d.ts +2 -0
- package/methods/pdf.js +1216 -0
- package/methods/pdf.js.map +1 -0
- package/methods/publications.d.ts +1 -0
- package/methods/publications.js +183 -0
- package/methods/publications.js.map +1 -0
- package/methods/report-builder.d.ts +2 -0
- package/methods/report-builder.js +3094 -0
- package/methods/report-builder.js.map +1 -0
- package/methods/support.d.ts +2 -0
- package/methods/support.js +430 -0
- package/methods/support.js.map +1 -0
- package/models/ai-run.model.d.ts +19 -0
- package/models/ai-run.model.js +4 -0
- package/models/ai-run.model.js.map +1 -0
- package/models/ai-terminal-conversation.model.d.ts +17 -0
- package/models/ai-terminal-conversation.model.js +4 -0
- package/models/ai-terminal-conversation.model.js.map +1 -0
- package/models/ai-terminal-issue-report.model.d.ts +19 -0
- package/models/ai-terminal-issue-report.model.js +4 -0
- package/models/ai-terminal-issue-report.model.js.map +1 -0
- package/models/ai-terminal-message.model.d.ts +22 -0
- package/models/ai-terminal-message.model.js +4 -0
- package/models/ai-terminal-message.model.js.map +1 -0
- package/models/app-setting.model.d.ts +16 -0
- package/models/app-setting.model.js +4 -0
- package/models/app-setting.model.js.map +1 -0
- package/{src/models/app-status.model.ts → models/app-status.model.d.ts} +2 -3
- package/models/app-status.model.js +4 -0
- package/models/app-status.model.js.map +1 -0
- package/{src/models/billing-logged-in-users.model.ts → models/billing-logged-in-users.model.d.ts} +4 -5
- package/models/billing-logged-in-users.model.js +4 -0
- package/models/billing-logged-in-users.model.js.map +1 -0
- package/models/collection-document.model.d.ts +21 -0
- package/models/collection-document.model.js +4 -0
- package/models/collection-document.model.js.map +1 -0
- package/models/communication-metric.model.d.ts +20 -0
- package/models/communication-metric.model.js +4 -0
- package/models/communication-metric.model.js.map +1 -0
- package/{src/models/counter.model.ts → models/counter.model.d.ts} +3 -4
- package/models/counter.model.js +4 -0
- package/models/counter.model.js.map +1 -0
- package/models/cron-job-history.model.d.ts +15 -0
- package/models/cron-job-history.model.js +4 -0
- package/models/cron-job-history.model.js.map +1 -0
- package/models/cron-job.model.d.ts +14 -0
- package/models/cron-job.model.js +4 -0
- package/models/cron-job.model.js.map +1 -0
- package/models/customer-notification.model.d.ts +26 -0
- package/models/customer-notification.model.js +4 -0
- package/models/customer-notification.model.js.map +1 -0
- package/models/customer-portal-password.model.d.ts +11 -0
- package/models/customer-portal-password.model.js +4 -0
- package/models/customer-portal-password.model.js.map +1 -0
- package/models/dialog.model.d.ts +23 -0
- package/models/dialog.model.js +4 -0
- package/models/dialog.model.js.map +1 -0
- package/models/email-history.model.d.ts +32 -0
- package/{src/models/email-history.model.ts → models/email-history.model.js} +4 -36
- package/models/email-history.model.js.map +1 -0
- package/{src/models/email-verified.model.ts → models/email-verified.model.d.ts} +5 -6
- package/models/email-verified.model.js +4 -0
- package/models/email-verified.model.js.map +1 -0
- package/{src/models/file.model.ts → models/file.model.d.ts} +7 -8
- package/models/file.model.js +4 -0
- package/models/file.model.js.map +1 -0
- package/{src/models/flag-update.model.ts → models/flag-update.model.d.ts} +3 -4
- package/models/flag-update.model.js +4 -0
- package/models/flag-update.model.js.map +1 -0
- package/{src/models/flag.model.ts → models/flag.model.d.ts} +3 -4
- package/models/flag.model.js +4 -0
- package/models/flag.model.js.map +1 -0
- package/models/log-method-latency.model.d.ts +10 -0
- package/models/log-method-latency.model.js +4 -0
- package/models/log-method-latency.model.js.map +1 -0
- package/{src/models/log-subscription.model.ts → models/log-subscription.model.d.ts} +9 -11
- package/models/log-subscription.model.js +4 -0
- package/models/log-subscription.model.js.map +1 -0
- package/models/log.model.d.ts +17 -0
- package/models/log.model.js +4 -0
- package/models/log.model.js.map +1 -0
- package/{src/models/logged-in-users.model.ts → models/logged-in-users.model.d.ts} +5 -6
- package/models/logged-in-users.model.js +4 -0
- package/models/logged-in-users.model.js.map +1 -0
- package/{src/models/method-response.model.ts → models/method-response.model.d.ts} +6 -7
- package/models/method-response.model.js +4 -0
- package/models/method-response.model.js.map +1 -0
- package/models/method.model.d.ts +26 -0
- package/models/method.model.js +4 -0
- package/models/method.model.js.map +1 -0
- package/{src/models/monitor-cpu.model.ts → models/monitor-cpu.model.d.ts} +7 -9
- package/models/monitor-cpu.model.js +4 -0
- package/models/monitor-cpu.model.js.map +1 -0
- package/models/monitor-function.model.d.ts +14 -0
- package/models/monitor-function.model.js +4 -0
- package/models/monitor-function.model.js.map +1 -0
- package/models/monitor-memory.model.d.ts +15 -0
- package/models/monitor-memory.model.js +4 -0
- package/models/monitor-memory.model.js.map +1 -0
- package/models/monitor-mongo.model.d.ts +13 -0
- package/models/monitor-mongo.model.js +4 -0
- package/models/monitor-mongo.model.js.map +1 -0
- package/{src/models/notification.model.ts → models/notification.model.d.ts} +4 -6
- package/models/notification.model.js +4 -0
- package/models/notification.model.js.map +1 -0
- package/models/openai-usage-ledger.model.d.ts +15 -0
- package/models/openai-usage-ledger.model.js +4 -0
- package/models/openai-usage-ledger.model.js.map +1 -0
- package/models/pagination.model.d.ts +11 -0
- package/models/pagination.model.js +28 -0
- package/models/pagination.model.js.map +1 -0
- package/models/permission.model.d.ts +12 -0
- package/models/permission.model.js +4 -0
- package/models/permission.model.js.map +1 -0
- package/models/report-builder-dashboard-builder.model.d.ts +25 -0
- package/models/report-builder-dashboard-builder.model.js +4 -0
- package/models/report-builder-dashboard-builder.model.js.map +1 -0
- package/models/report-builder-library.model.d.ts +17 -0
- package/models/report-builder-library.model.js +4 -0
- package/models/report-builder-library.model.js.map +1 -0
- package/models/report-builder-report.model.d.ts +121 -0
- package/models/report-builder-report.model.js +4 -0
- package/models/report-builder-report.model.js.map +1 -0
- package/models/report-builder.model.d.ts +61 -0
- package/models/report-builder.model.js +4 -0
- package/models/report-builder.model.js.map +1 -0
- package/models/select-data-label.model.d.ts +9 -0
- package/models/select-data-label.model.js +4 -0
- package/models/select-data-label.model.js.map +1 -0
- package/models/server-message.model.d.ts +32 -0
- package/models/server-message.model.js +4 -0
- package/models/server-message.model.js.map +1 -0
- package/models/slow-query-report.model.d.ts +23 -0
- package/models/slow-query-report.model.js +4 -0
- package/models/slow-query-report.model.js.map +1 -0
- package/models/subscription.model.d.ts +31 -0
- package/models/subscription.model.js +4 -0
- package/models/subscription.model.js.map +1 -0
- package/models/support-ticket.model.d.ts +87 -0
- package/models/support-ticket.model.js +4 -0
- package/models/support-ticket.model.js.map +1 -0
- package/models/user-group.model.d.ts +20 -0
- package/models/user-group.model.js +4 -0
- package/models/user-group.model.js.map +1 -0
- package/{src/models/user-guide.model.ts → models/user-guide.model.d.ts} +4 -5
- package/models/user-guide.model.js +4 -0
- package/models/user-guide.model.js.map +1 -0
- package/models/user.model.d.ts +84 -0
- package/models/user.model.js +4 -0
- package/models/user.model.js.map +1 -0
- package/package.json +1 -1
- package/private/images/ResolveIO.png +0 -0
- package/public_api.js +127 -0
- package/public_api.js.map +1 -0
- package/publications/ai-terminal.d.ts +1 -0
- package/publications/ai-terminal.js +122 -0
- package/publications/ai-terminal.js.map +1 -0
- package/publications/app-settings.d.ts +2 -0
- package/publications/app-settings.js +28 -0
- package/publications/app-settings.js.map +1 -0
- package/publications/app-status.d.ts +2 -0
- package/publications/app-status.js +16 -0
- package/publications/app-status.js.map +1 -0
- package/publications/cron-jobs.d.ts +2 -0
- package/publications/cron-jobs.js +88 -0
- package/publications/cron-jobs.js.map +1 -0
- package/publications/customer-notifications.d.ts +2 -0
- package/publications/customer-notifications.js +161 -0
- package/publications/customer-notifications.js.map +1 -0
- package/publications/files.d.ts +2 -0
- package/publications/files.js +36 -0
- package/publications/files.js.map +1 -0
- package/publications/flags-update.d.ts +2 -0
- package/publications/flags-update.js +22 -0
- package/publications/flags-update.js.map +1 -0
- package/publications/flags.d.ts +2 -0
- package/publications/flags.js +22 -0
- package/publications/flags.js.map +1 -0
- package/publications/logs.d.ts +2 -0
- package/publications/logs.js +164 -0
- package/publications/logs.js.map +1 -0
- package/publications/notifications.d.ts +2 -0
- package/publications/notifications.js +16 -0
- package/publications/notifications.js.map +1 -0
- package/publications/report-builder-dashboard-builders.d.ts +2 -0
- package/publications/report-builder-dashboard-builders.js +42 -0
- package/publications/report-builder-dashboard-builders.js.map +1 -0
- package/publications/report-builder-libraries.d.ts +2 -0
- package/publications/report-builder-libraries.js +90 -0
- package/publications/report-builder-libraries.js.map +1 -0
- package/publications/report-builder-reports.d.ts +2 -0
- package/publications/report-builder-reports.js +50 -0
- package/publications/report-builder-reports.js.map +1 -0
- package/publications/super-admin.d.ts +2 -0
- package/publications/super-admin.js +16 -0
- package/publications/super-admin.js.map +1 -0
- package/publications/user-groups.d.ts +1 -0
- package/publications/user-groups.js +16 -0
- package/publications/user-groups.js.map +1 -0
- package/publications/user-guides.d.ts +1 -0
- package/publications/user-guides.js +16 -0
- package/publications/user-guides.js.map +1 -0
- package/resolveio-server-app.d.ts +70 -0
- package/resolveio-server-app.js +801 -0
- package/resolveio-server-app.js.map +1 -0
- package/server-app.d.ts +228 -0
- package/server-app.js +3566 -0
- package/server-app.js.map +1 -0
- package/services/codex-client.d.ts +128 -0
- package/services/codex-client.js +1629 -0
- package/services/codex-client.js.map +1 -0
- package/services/openai-client.d.ts +46 -0
- package/services/openai-client.js +318 -0
- package/services/openai-client.js.map +1 -0
- package/types/error-report.d.ts +25 -0
- package/types/error-report.js +4 -0
- package/types/error-report.js.map +1 -0
- package/types/slow-query-report.d.ts +27 -0
- package/types/slow-query-report.js +6 -0
- package/types/slow-query-report.js.map +1 -0
- package/util/ai-qa-policy.d.ts +124 -0
- package/util/ai-qa-policy.js +736 -0
- package/util/ai-qa-policy.js.map +1 -0
- package/util/ai-run-evidence-adapters.d.ts +33 -0
- package/util/ai-run-evidence-adapters.js +831 -0
- package/util/ai-run-evidence-adapters.js.map +1 -0
- package/util/ai-run-evidence-dashboard.d.ts +67 -0
- package/util/ai-run-evidence-dashboard.js +309 -0
- package/util/ai-run-evidence-dashboard.js.map +1 -0
- package/util/ai-run-evidence-eval.d.ts +86 -0
- package/util/ai-run-evidence-eval.js +854 -0
- package/util/ai-run-evidence-eval.js.map +1 -0
- package/util/ai-run-evidence.d.ts +212 -0
- package/util/ai-run-evidence.js +649 -0
- package/util/ai-run-evidence.js.map +1 -0
- package/util/ai-runner-artifacts.d.ts +82 -0
- package/util/ai-runner-artifacts.js +713 -0
- package/util/ai-runner-artifacts.js.map +1 -0
- package/util/ai-runner-manager-autopilot.d.ts +92 -0
- package/util/ai-runner-manager-autopilot.js +281 -0
- package/util/ai-runner-manager-autopilot.js.map +1 -0
- package/util/ai-runner-manager-policy.d.ts +282 -0
- package/util/ai-runner-manager-policy.js +997 -0
- package/util/ai-runner-manager-policy.js.map +1 -0
- package/util/ai-runner-qa-auth.d.ts +5 -0
- package/util/ai-runner-qa-auth.js +822 -0
- package/util/ai-runner-qa-auth.js.map +1 -0
- package/util/ai-runner-qa-tools.d.ts +26 -0
- package/util/ai-runner-qa-tools.js +3029 -0
- package/util/ai-runner-qa-tools.js.map +1 -0
- package/util/aicoder-runner-v6.d.ts +214 -0
- package/util/aicoder-runner-v6.js +507 -0
- package/util/aicoder-runner-v6.js.map +1 -0
- package/util/common.d.ts +31 -0
- package/util/common.js +683 -0
- package/util/common.js.map +1 -0
- package/util/customer-portal-password.d.ts +13 -0
- package/util/customer-portal-password.js +209 -0
- package/util/customer-portal-password.js.map +1 -0
- package/util/error-reporter.d.ts +52 -0
- package/util/error-reporter.js +326 -0
- package/util/error-reporter.js.map +1 -0
- package/util/error-tracking.d.ts +13 -0
- package/util/error-tracking.js +120 -0
- package/util/error-tracking.js.map +1 -0
- package/util/openai-usage-cost.d.ts +6 -0
- package/util/openai-usage-cost.js +103 -0
- package/util/openai-usage-cost.js.map +1 -0
- package/util/report-builder-unwinds.d.ts +15 -0
- package/util/report-builder-unwinds.js +156 -0
- package/util/report-builder-unwinds.js.map +1 -0
- package/util/runner-process-janitor.d.ts +27 -0
- package/util/runner-process-janitor.js +208 -0
- package/util/runner-process-janitor.js.map +1 -0
- package/util/schema-report-builder.d.ts +6 -0
- package/util/schema-report-builder.js +481 -0
- package/util/schema-report-builder.js.map +1 -0
- package/util/slow-query-reporter.d.ts +28 -0
- package/util/slow-query-reporter.js +226 -0
- package/util/slow-query-reporter.js.map +1 -0
- package/util/subscription-dependency-context.d.ts +34 -0
- package/util/subscription-dependency-context.js +1283 -0
- package/util/subscription-dependency-context.js.map +1 -0
- package/util/support-runner-v5.d.ts +415 -0
- package/util/support-runner-v5.js +1445 -0
- package/util/support-runner-v5.js.map +1 -0
- package/util/tokenizer.d.ts +5 -0
- package/util/tokenizer.js +41 -0
- package/util/tokenizer.js.map +1 -0
- package/workers/codex-runner.worker.d.ts +1 -0
- package/workers/codex-runner.worker.js +192 -0
- package/workers/codex-runner.worker.js.map +1 -0
- package/.nodemon.json +0 -5
- package/.vscode/settings.json +0 -21
- package/AGENTS.md +0 -195
- package/README.md +0 -22
- package/build_package.sh +0 -5
- package/compileDTS.pl +0 -64
- package/docs/ai-assistant-nightly-eval.md +0 -65
- package/docs/ai-assistant-preflight-checklist.md +0 -23
- package/docs/ai-assistant-report-builder-bridge-playbook.md +0 -115
- package/eslint-plugin-custom/index.js +0 -7
- package/eslint-plugin-custom/rules/no-filter-zero-index.js +0 -44
- package/eslint.config.js +0 -103
- package/gulpfile.js +0 -216
- package/methodAndPublicationListGenerator.py +0 -375
- package/mongodbensurers.js +0 -2
- package/mongostop.js +0 -3
- package/scripts/cleanup-bypassed-callmethod-logs.js +0 -616
- package/settings.development.json +0 -25
- package/settings.development.redacted.json +0 -25
- package/src/.env +0 -12
- package/src/ai/assistant-core-heuristics.ts +0 -379
- package/src/ai/resolveio-platform-intelligence-memory-corpus.ts +0 -185
- package/src/ai/resolveio-platform-intelligence-memory.ts +0 -325
- package/src/ai/resolveio-platform-intelligence.ts +0 -462
- package/src/client-server-app.ts +0 -12
- package/src/collections/ai-run.collection.ts +0 -117
- package/src/collections/ai-terminal-conversation.collection.ts +0 -91
- package/src/collections/ai-terminal-issue-report.collection.ts +0 -99
- package/src/collections/ai-terminal-message.collection.ts +0 -77
- package/src/collections/app-setting.collection.ts +0 -104
- package/src/collections/app-status.collection.ts +0 -58
- package/src/collections/communication-metric.collection.ts +0 -84
- package/src/collections/counter.collection.ts +0 -56
- package/src/collections/cron-job-history.collection.ts +0 -94
- package/src/collections/cron-job.collection.ts +0 -92
- package/src/collections/customer-notification.collection.ts +0 -131
- package/src/collections/customer-portal-password.collection.ts +0 -76
- package/src/collections/email-history.collection.ts +0 -134
- package/src/collections/email-verified.collection.ts +0 -62
- package/src/collections/file.collection.ts +0 -74
- package/src/collections/flag-update.collection.ts +0 -57
- package/src/collections/flag.collection.ts +0 -57
- package/src/collections/log-method-latency.collection.ts +0 -77
- package/src/collections/log-subscription.collection.ts +0 -80
- package/src/collections/log.collection.ts +0 -93
- package/src/collections/logged-in-users.collection.ts +0 -67
- package/src/collections/monitor-cpu.collection.ts +0 -65
- package/src/collections/monitor-function.collection.ts +0 -74
- package/src/collections/monitor-memory.collection.ts +0 -77
- package/src/collections/monitor-mongo.collection.ts +0 -71
- package/src/collections/notification.collection.ts +0 -57
- package/src/collections/openai-usage-ledger.collection.ts +0 -77
- package/src/collections/report-builder-dashboard-builder.collection.ts +0 -109
- package/src/collections/report-builder-library.collection.ts +0 -89
- package/src/collections/report-builder-report.collection.ts +0 -184
- package/src/collections/user-group.collection.ts +0 -89
- package/src/collections/user-guide.collection.ts +0 -57
- package/src/collections/user.collection.ts +0 -181
- package/src/cron/cron.ts +0 -117
- package/src/fixtures/cron-jobs.ts +0 -95
- package/src/fixtures/init.ts +0 -35
- package/src/http/auth.ts +0 -818
- package/src/http/health.ts +0 -7
- package/src/http/home.ts +0 -90
- package/src/http/slow-query-publication.ts +0 -49
- package/src/index.ts +0 -1
- package/src/managers/ai-assistant-codex-manager.manager.ts +0 -1131
- package/src/managers/ai-run-evidence.manager.ts +0 -264
- package/src/managers/communication-metric.manager.ts +0 -82
- package/src/managers/cron.manager.ts +0 -333
- package/src/managers/customer-notification-content.manager.ts +0 -236
- package/src/managers/diagnostic-manager-bootstrap.ts +0 -165
- package/src/managers/error-auto-fix.manager.ts +0 -2767
- package/src/managers/local-log.manager.ts +0 -113
- package/src/managers/method.manager.ts +0 -1857
- package/src/managers/mongo.manager.ts +0 -4575
- package/src/managers/monitor.manager.ts +0 -507
- package/src/managers/openai-usage-ledger.manager.ts +0 -57
- package/src/managers/slow-query-verifier.manager.ts +0 -3590
- package/src/managers/slow-query.manager.ts +0 -519
- package/src/managers/subscription.manager.ts +0 -3128
- package/src/managers/websocket.manager.ts +0 -746
- package/src/managers/worker-dispatcher.manager.ts +0 -1360
- package/src/managers/worker-server.manager.ts +0 -536
- package/src/methods/accounts.ts +0 -532
- package/src/methods/ai-terminal.ts +0 -23497
- package/src/methods/app-settings.ts +0 -114
- package/src/methods/aws.ts +0 -649
- package/src/methods/collections.ts +0 -641
- package/src/methods/counters.ts +0 -69
- package/src/methods/cron-jobs.ts +0 -2614
- package/src/methods/customer-notifications.ts +0 -458
- package/src/methods/diagnostics.ts +0 -616
- package/src/methods/flag-updates.ts +0 -7
- package/src/methods/flags.ts +0 -7
- package/src/methods/logs.ts +0 -657
- package/src/methods/mongo-explorer.ts +0 -1880
- package/src/methods/monitor.ts +0 -540
- package/src/methods/pdf.ts +0 -1236
- package/src/methods/publications.ts +0 -129
- package/src/methods/report-builder.ts +0 -3300
- package/src/methods/support.ts +0 -335
- package/src/models/ai-run.model.ts +0 -27
- package/src/models/ai-terminal-conversation.model.ts +0 -19
- package/src/models/ai-terminal-issue-report.model.ts +0 -21
- package/src/models/ai-terminal-message.model.ts +0 -24
- package/src/models/app-setting.model.ts +0 -17
- package/src/models/collection-document.model.ts +0 -24
- package/src/models/communication-metric.model.ts +0 -23
- package/src/models/cron-job-history.model.ts +0 -16
- package/src/models/cron-job.model.ts +0 -15
- package/src/models/customer-notification.model.ts +0 -28
- package/src/models/customer-portal-password.model.ts +0 -12
- package/src/models/dialog.model.ts +0 -25
- package/src/models/log-method-latency.model.ts +0 -11
- package/src/models/log.model.ts +0 -19
- package/src/models/method.model.ts +0 -25
- package/src/models/monitor-function.model.ts +0 -16
- package/src/models/monitor-memory.model.ts +0 -17
- package/src/models/monitor-mongo.model.ts +0 -15
- package/src/models/openai-usage-ledger.model.ts +0 -16
- package/src/models/pagination.model.ts +0 -35
- package/src/models/permission.model.ts +0 -14
- package/src/models/report-builder-dashboard-builder.model.ts +0 -29
- package/src/models/report-builder-library.model.ts +0 -20
- package/src/models/report-builder-report.model.ts +0 -136
- package/src/models/report-builder.model.ts +0 -68
- package/src/models/select-data-label.model.ts +0 -9
- package/src/models/server-message.model.ts +0 -31
- package/src/models/slow-query-report.model.ts +0 -23
- package/src/models/subscription.model.ts +0 -73
- package/src/models/support-ticket.model.ts +0 -104
- package/src/models/user-group.model.ts +0 -24
- package/src/models/user.model.ts +0 -96
- package/src/private/images/ResolveIO.png +0 -0
- package/src/publications/ai-terminal.ts +0 -73
- package/src/publications/app-settings.ts +0 -25
- package/src/publications/app-status.ts +0 -13
- package/src/publications/cron-jobs.ts +0 -40
- package/src/publications/customer-notifications.ts +0 -101
- package/src/publications/files.ts +0 -33
- package/src/publications/flags-update.ts +0 -19
- package/src/publications/flags.ts +0 -19
- package/src/publications/logs.ts +0 -163
- package/src/publications/notifications.ts +0 -13
- package/src/publications/report-builder-dashboard-builders.ts +0 -39
- package/src/publications/report-builder-libraries.ts +0 -41
- package/src/publications/report-builder-reports.ts +0 -47
- package/src/publications/super-admin.ts +0 -13
- package/src/publications/user-groups.ts +0 -12
- package/src/publications/user-guides.ts +0 -12
- package/src/resolveio-server-app.ts +0 -617
- package/src/server-app.ts +0 -3354
- package/src/services/codex-client.ts +0 -1231
- package/src/services/openai-client.ts +0 -265
- package/src/types/error-report.ts +0 -26
- package/src/types/js-tiktoken.d.ts +0 -11
- package/src/types/slow-query-report.ts +0 -28
- package/src/util/ai-qa-policy.ts +0 -925
- package/src/util/ai-run-evidence-adapters.ts +0 -677
- package/src/util/ai-run-evidence-dashboard.ts +0 -271
- package/src/util/ai-run-evidence-eval.ts +0 -885
- package/src/util/ai-run-evidence.ts +0 -964
- package/src/util/ai-runner-artifacts.ts +0 -586
- package/src/util/ai-runner-manager-autopilot.ts +0 -380
- package/src/util/ai-runner-manager-policy.ts +0 -1740
- package/src/util/ai-runner-qa-auth.ts +0 -821
- package/src/util/ai-runner-qa-tools.ts +0 -3045
- package/src/util/aicoder-runner-v6.ts +0 -875
- package/src/util/common.ts +0 -649
- package/src/util/customer-portal-password.ts +0 -183
- package/src/util/error-reporter.ts +0 -332
- package/src/util/error-tracking.ts +0 -79
- package/src/util/openai-usage-cost.ts +0 -114
- package/src/util/report-builder-unwinds.ts +0 -180
- package/src/util/runner-process-janitor.ts +0 -219
- package/src/util/schema-report-builder.ts +0 -448
- package/src/util/slow-query-reporter.ts +0 -216
- package/src/util/subscription-dependency-context.ts +0 -1096
- package/src/util/support-runner-v5.ts +0 -2065
- package/src/util/tokenizer.ts +0 -38
- package/src/workers/codex-runner.worker.ts +0 -142
- package/start_server.sh +0 -5
- package/tests/ai-assistant-corpus-build.ts +0 -484
- package/tests/ai-assistant-corpus-replay-e2e.ts +0 -774
- package/tests/ai-assistant-data-parity-e2e.ts +0 -1989
- package/tests/ai-assistant-eval-triage.ts +0 -831
- package/tests/ai-assistant-openai-e2e.ts +0 -1061
- package/tests/ai-assistant-openai-git-e2e.ts +0 -155
- package/tests/ai-assistant-preflight-matrix.ts +0 -215
- package/tests/ai-assistant-routing-eval.test.ts +0 -560
- package/tests/ai-assistant-snf-live-eval.ts +0 -975
- package/tests/ai-assistant-utils.test.ts +0 -2968
- package/tests/ai-manager-autopilot-snapshot.test.ts +0 -172
- package/tests/ai-manager-recovery-checkpoint.test.ts +0 -323
- package/tests/ai-run-eval.test.ts +0 -88
- package/tests/ai-run-evidence.test.ts +0 -305
- package/tests/ai-runner-contract.test.ts +0 -488
- package/tests/aicoder-runner-v6.test.ts +0 -268
- package/tests/error-reporter.test.ts +0 -145
- package/tests/method-publication-generator.test.ts +0 -46
- package/tests/report-builder-linking.test.ts +0 -79
- package/tests/resolveio-platform-intelligence.test.ts +0 -352
- package/tests/server-app-cron-owner.test.ts +0 -127
- package/tests/subscription-connect-race.test.ts +0 -158
- package/tests/subscription-dependency-context.test.ts +0 -324
- package/tests/subscription-manager-collection-tracking.test.ts +0 -86
- package/tests/subscription-manager-invalidation.test.ts +0 -86
- package/tests/support-runner-v5.test.ts +0 -417
- package/tsconfig.json +0 -34
- /package/{src/private → private}/email-templates/enrollment.html +0 -0
- /package/{src/private → private}/email-templates/forgot-password.html +0 -0
- /package/{src/private → private}/email-templates/support-ticket-deleted.html +0 -0
- /package/{src/private → private}/email-templates/support-ticket-modified.html +0 -0
- /package/{src/private → private}/email-templates/support-ticket.html +0 -0
- /package/{src/public_api.ts → public_api.d.ts} +0 -0
|
@@ -1,2065 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildResolveIOAIManagerRecoveryCheckpoint,
|
|
3
|
-
buildResolveIOAIManagerRecoveryActionPacket,
|
|
4
|
-
buildResolveIOAIManagerRecoveryEvidenceProbe,
|
|
5
|
-
buildResolveIOAIManagerRecoveryPlan,
|
|
6
|
-
decideResolveIOAIManagerPolicy,
|
|
7
|
-
hashResolveIOAIManagerEvidence,
|
|
8
|
-
ResolveIOAIManagerRecoveryCheckpoint,
|
|
9
|
-
ResolveIOAIManagerRecoveryActionPacket,
|
|
10
|
-
ResolveIOAIManagerRecoveryActionDispatchRecord,
|
|
11
|
-
ResolveIOAIManagerRecoveryExecutionDirective,
|
|
12
|
-
ResolveIOAIManagerRecoveryEvidenceProbe,
|
|
13
|
-
ResolveIOAIManagerRecoveryPlan,
|
|
14
|
-
ResolveIOAIManagerRecoveryPlanInput
|
|
15
|
-
} from './ai-runner-manager-policy';
|
|
16
|
-
|
|
17
|
-
export type ResolveIOSupportV5StepType =
|
|
18
|
-
| 'diagnosis_gate'
|
|
19
|
-
| 'reproduction_probe'
|
|
20
|
-
| 'issue_class_probe'
|
|
21
|
-
| 'business_proof'
|
|
22
|
-
| 'compile_check'
|
|
23
|
-
| 'startup_check'
|
|
24
|
-
| 'live_seed'
|
|
25
|
-
| 'auth_bootstrap'
|
|
26
|
-
| 'route_probe'
|
|
27
|
-
| 'qa_row'
|
|
28
|
-
| 'build_repair'
|
|
29
|
-
| 'qa_retest'
|
|
30
|
-
| 'pr_review'
|
|
31
|
-
| 'artifact_package'
|
|
32
|
-
| 'cleanup';
|
|
33
|
-
|
|
34
|
-
export type ResolveIOSupportV5Outcome =
|
|
35
|
-
| 'pass'
|
|
36
|
-
| 'needs_repair'
|
|
37
|
-
| 'retry_same_step'
|
|
38
|
-
| 'park_manual'
|
|
39
|
-
| 'budget_stop'
|
|
40
|
-
| 'infra_retry'
|
|
41
|
-
| 'ready_for_merge';
|
|
42
|
-
|
|
43
|
-
export type ResolveIOSupportV5Lane = 'build' | 'qa' | 'review' | 'supervisor';
|
|
44
|
-
|
|
45
|
-
export type ResolveIOSupportIssueClass =
|
|
46
|
-
| 'no_op_submit'
|
|
47
|
-
| 'missing_wrong_data'
|
|
48
|
-
| 'filter_query_mismatch'
|
|
49
|
-
| 'invoice_pdf_export'
|
|
50
|
-
| 'upload_import'
|
|
51
|
-
| 'route_auth_hydration'
|
|
52
|
-
| 'slow_query_performance';
|
|
53
|
-
|
|
54
|
-
export type ResolveIOSupportDiagnosisGateStatus = 'missing' | 'incomplete' | 'blocked' | 'passed';
|
|
55
|
-
|
|
56
|
-
export type ResolveIOSupportV5FailureClass =
|
|
57
|
-
| 'diagnosis'
|
|
58
|
-
| 'infra'
|
|
59
|
-
| 'compile'
|
|
60
|
-
| 'route'
|
|
61
|
-
| 'business'
|
|
62
|
-
| 'product_code'
|
|
63
|
-
| 'qa_evidence'
|
|
64
|
-
| 'release'
|
|
65
|
-
| 'unknown';
|
|
66
|
-
|
|
67
|
-
export interface ResolveIOSupportDiagnosisIssueCase {
|
|
68
|
-
customer_complaint: string;
|
|
69
|
-
expected_result: string;
|
|
70
|
-
observed_result: string;
|
|
71
|
-
route_module: string;
|
|
72
|
-
account_customer_context: string;
|
|
73
|
-
reproduction_status: 'reproduced' | 'blocked' | 'classified';
|
|
74
|
-
reproduction_blocker?: string;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface ResolveIOSupportDiagnosisHypothesis {
|
|
78
|
-
statement: string;
|
|
79
|
-
falsifiable_test: string;
|
|
80
|
-
evidence: string[];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export interface ResolveIOSupportDiagnosisFailingPath {
|
|
84
|
-
frontend?: string;
|
|
85
|
-
backend?: string;
|
|
86
|
-
shared_library?: string;
|
|
87
|
-
data_query?: string;
|
|
88
|
-
description: string;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface ResolveIOSupportDiagnosisProofPlan {
|
|
92
|
-
before: string;
|
|
93
|
-
before_state_unavailable_reason?: string;
|
|
94
|
-
action: string;
|
|
95
|
-
after: string;
|
|
96
|
-
business_assertion: string;
|
|
97
|
-
route?: string;
|
|
98
|
-
data_assertion?: string;
|
|
99
|
-
artifact_expectation?: string;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export interface ResolveIOSupportDiagnosisHint {
|
|
103
|
-
id?: string;
|
|
104
|
-
ticketNumber?: string;
|
|
105
|
-
title?: string;
|
|
106
|
-
outcome?: string;
|
|
107
|
-
issueClass?: string;
|
|
108
|
-
ownerFiles?: string[];
|
|
109
|
-
commitSha?: string;
|
|
110
|
-
commitMessage?: string;
|
|
111
|
-
reason?: string;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export interface ResolveIOSupportDiagnosisEvidence {
|
|
115
|
-
type: 'ticket' | 'browser' | 'mongo' | 'log' | 'code' | 'commit' | 'qa' | 'other';
|
|
116
|
-
summary: string;
|
|
117
|
-
artifactPath?: string;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface ResolveIOSupportDiagnosisGate {
|
|
121
|
-
issue_case: ResolveIOSupportDiagnosisIssueCase;
|
|
122
|
-
issue_class: ResolveIOSupportIssueClass;
|
|
123
|
-
accepted_hypothesis: ResolveIOSupportDiagnosisHypothesis;
|
|
124
|
-
rejected_alternatives: string[];
|
|
125
|
-
failing_path: ResolveIOSupportDiagnosisFailingPath;
|
|
126
|
-
owner_files: string[];
|
|
127
|
-
proof_plan: ResolveIOSupportDiagnosisProofPlan;
|
|
128
|
-
similar_tickets?: ResolveIOSupportDiagnosisHint[];
|
|
129
|
-
similar_commits?: ResolveIOSupportDiagnosisHint[];
|
|
130
|
-
evidence: ResolveIOSupportDiagnosisEvidence[];
|
|
131
|
-
status: ResolveIOSupportDiagnosisGateStatus;
|
|
132
|
-
updatedAt?: string;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export interface ResolveIOSupportDiagnosisGateValidation {
|
|
136
|
-
valid: boolean;
|
|
137
|
-
status: ResolveIOSupportDiagnosisGateStatus;
|
|
138
|
-
blockers: string[];
|
|
139
|
-
normalized?: ResolveIOSupportDiagnosisGate;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export interface ResolveIOSupportIssueClassProbe {
|
|
143
|
-
issue_class: ResolveIOSupportIssueClass;
|
|
144
|
-
probe_type: ResolveIOSupportV5StepType;
|
|
145
|
-
objective: string;
|
|
146
|
-
route?: string;
|
|
147
|
-
action: string;
|
|
148
|
-
expected_evidence: string;
|
|
149
|
-
blocks_acceptance_without_business_assertion: boolean;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export interface ResolveIOSupportV5RepeatStopInput {
|
|
153
|
-
history: ResolveIOSupportV5StepRecord[];
|
|
154
|
-
failureClass?: ResolveIOSupportV5FailureClass | string;
|
|
155
|
-
blocker?: string;
|
|
156
|
-
evidence?: any;
|
|
157
|
-
evidenceHash?: string;
|
|
158
|
-
limit?: number;
|
|
159
|
-
ignoreInfra?: boolean;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export interface ResolveIOSupportV5RepeatStopDecision {
|
|
163
|
-
shouldStop: boolean;
|
|
164
|
-
repeatedCount: number;
|
|
165
|
-
failureClass: string;
|
|
166
|
-
blockerFingerprint: string;
|
|
167
|
-
evidenceHash: string;
|
|
168
|
-
reason: string;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export type ResolveIOSupportV5RepairGateAction =
|
|
172
|
-
| 'diagnose_only'
|
|
173
|
-
| 'infra_repair_only'
|
|
174
|
-
| 'allow_product_repair'
|
|
175
|
-
| 'reject_out_of_scope'
|
|
176
|
-
| 'park_repeated_failure';
|
|
177
|
-
|
|
178
|
-
export interface ResolveIOSupportV5RepairGateInput {
|
|
179
|
-
diagnosisGate?: any;
|
|
180
|
-
activeStepType?: ResolveIOSupportV5StepType | string;
|
|
181
|
-
changedFiles?: any;
|
|
182
|
-
failureClass?: ResolveIOSupportV5FailureClass | string;
|
|
183
|
-
blocker?: string;
|
|
184
|
-
evidence?: any;
|
|
185
|
-
evidenceHash?: string;
|
|
186
|
-
history?: ResolveIOSupportV5StepRecord[];
|
|
187
|
-
maxOwnerFiles?: number;
|
|
188
|
-
maxRepeatedNoProgress?: number;
|
|
189
|
-
allowTestsOutsideOwnerFiles?: boolean;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export interface ResolveIOSupportV5RepairGateDecision {
|
|
193
|
-
action: ResolveIOSupportV5RepairGateAction;
|
|
194
|
-
canEditProductCode: boolean;
|
|
195
|
-
blockers: string[];
|
|
196
|
-
ownerFiles: string[];
|
|
197
|
-
issueClass?: ResolveIOSupportIssueClass;
|
|
198
|
-
proofPlan?: ResolveIOSupportDiagnosisProofPlan;
|
|
199
|
-
outsideOwnerFiles: string[];
|
|
200
|
-
repeatedFailure?: ResolveIOSupportV5RepeatStopDecision;
|
|
201
|
-
diagnosisValidation: ResolveIOSupportDiagnosisGateValidation;
|
|
202
|
-
recoveryPlan: ResolveIOAIManagerRecoveryPlan;
|
|
203
|
-
recoveryCheckpoint: ResolveIOAIManagerRecoveryCheckpoint;
|
|
204
|
-
recoveryEvidenceProbe: ResolveIOAIManagerRecoveryEvidenceProbe;
|
|
205
|
-
recoveryAction: ResolveIOAIManagerRecoveryActionPacket;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export type ResolveIOSupportV5MicrotaskStatus =
|
|
209
|
-
| 'pending'
|
|
210
|
-
| 'in_progress'
|
|
211
|
-
| 'pass'
|
|
212
|
-
| 'needs_repair'
|
|
213
|
-
| 'blocked'
|
|
214
|
-
| 'parked';
|
|
215
|
-
|
|
216
|
-
export type ResolveIOSupportV5MicrotaskType =
|
|
217
|
-
| ResolveIOSupportV5StepType
|
|
218
|
-
| 'planning'
|
|
219
|
-
| 'scope_slice'
|
|
220
|
-
| 'product_repair'
|
|
221
|
-
| 'runner_repair';
|
|
222
|
-
|
|
223
|
-
export interface ResolveIOSupportV5PromptBudget {
|
|
224
|
-
initialPlannerCap: number;
|
|
225
|
-
buildMicrotaskCap: number;
|
|
226
|
-
buildMicrotaskHardCap: number;
|
|
227
|
-
qaMicrotaskCap: number;
|
|
228
|
-
qaMicrotaskHardCap: number;
|
|
229
|
-
repairMicrotaskCap: number;
|
|
230
|
-
repairMicrotaskHardCap: number;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export interface ResolveIOSupportV5Microtask {
|
|
234
|
-
microtaskId: string;
|
|
235
|
-
lane: ResolveIOSupportV5Lane;
|
|
236
|
-
type: ResolveIOSupportV5MicrotaskType;
|
|
237
|
-
status: ResolveIOSupportV5MicrotaskStatus;
|
|
238
|
-
objective: string;
|
|
239
|
-
targetFiles: string[];
|
|
240
|
-
contextRefs: string[];
|
|
241
|
-
selfGate: string;
|
|
242
|
-
acceptanceProof: string;
|
|
243
|
-
threadKey: string;
|
|
244
|
-
promptTokenEstimate?: number;
|
|
245
|
-
attempts: number;
|
|
246
|
-
dependsOn: string[];
|
|
247
|
-
parentScopeId?: string;
|
|
248
|
-
blocker?: string;
|
|
249
|
-
createdAt: string;
|
|
250
|
-
updatedAt: string;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
export interface ResolveIOSupportV5UsageSection {
|
|
254
|
-
name: string;
|
|
255
|
-
tokenEstimate: number;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export interface ResolveIOSupportV5MicrotaskUsage {
|
|
259
|
-
microtaskId: string;
|
|
260
|
-
lane: ResolveIOSupportV5Lane;
|
|
261
|
-
model?: string;
|
|
262
|
-
threadKey?: string;
|
|
263
|
-
reuseThread: boolean;
|
|
264
|
-
freshReason?: string;
|
|
265
|
-
promptTokenEstimate: number;
|
|
266
|
-
promptSections: ResolveIOSupportV5UsageSection[];
|
|
267
|
-
actualInputTokens?: number;
|
|
268
|
-
actualCachedInputTokens?: number;
|
|
269
|
-
actualOutputTokens?: number;
|
|
270
|
-
durationMs?: number;
|
|
271
|
-
outcome?: ResolveIOSupportV5Outcome | ResolveIOSupportV5MicrotaskStatus;
|
|
272
|
-
recordedAt: string;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
export interface ResolveIOSupportV5Budget {
|
|
276
|
-
maxPromptTokensPerNonInitialStep: number;
|
|
277
|
-
maxLoopsPerTicket: number;
|
|
278
|
-
maxRepeatedNoProgress: number;
|
|
279
|
-
maxRuntimeMinutesPerLoop: number;
|
|
280
|
-
totalPromptTokenEstimate: number;
|
|
281
|
-
totalRuntimeMs: number;
|
|
282
|
-
loopCount: number;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
export interface ResolveIOSupportV5LaneMemory {
|
|
286
|
-
lane: ResolveIOSupportV5Lane;
|
|
287
|
-
model: string;
|
|
288
|
-
threadKey: string;
|
|
289
|
-
scopeSummary: string;
|
|
290
|
-
activeBlocker: string;
|
|
291
|
-
activeQaRow?: {
|
|
292
|
-
index?: number;
|
|
293
|
-
workflow?: string;
|
|
294
|
-
route?: string;
|
|
295
|
-
assertion?: string;
|
|
296
|
-
status?: string;
|
|
297
|
-
};
|
|
298
|
-
changedFiles: string[];
|
|
299
|
-
artifactPaths: string[];
|
|
300
|
-
latestPromptTokenEstimate?: number;
|
|
301
|
-
updatedAt: string;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
export interface ResolveIOSupportV5FailureFingerprint {
|
|
305
|
-
stepType: ResolveIOSupportV5StepType;
|
|
306
|
-
failureClass: string;
|
|
307
|
-
blockerFingerprint: string;
|
|
308
|
-
evidenceHash: string;
|
|
309
|
-
recordedAt: string;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
export interface ResolveIOSupportV5SupervisorState {
|
|
313
|
-
version: 'v5';
|
|
314
|
-
status: 'active' | 'parked' | 'complete';
|
|
315
|
-
currentGoal: string;
|
|
316
|
-
approvedScope: string;
|
|
317
|
-
prBranch: string;
|
|
318
|
-
activeStep: ResolveIOSupportV5StepType;
|
|
319
|
-
activeBlocker: string;
|
|
320
|
-
lastGoodCheckpoint: string;
|
|
321
|
-
currentQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];
|
|
322
|
-
processLease?: {
|
|
323
|
-
runId?: string;
|
|
324
|
-
token?: string;
|
|
325
|
-
generation?: number;
|
|
326
|
-
workspace?: string;
|
|
327
|
-
lane?: string;
|
|
328
|
-
};
|
|
329
|
-
artifactLinks: string[];
|
|
330
|
-
noEmailUnlessApproved: boolean;
|
|
331
|
-
updatedAt: string;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
export interface ResolveIOSupportV5StepRecord {
|
|
335
|
-
microtaskId?: string;
|
|
336
|
-
stepType: ResolveIOSupportV5StepType;
|
|
337
|
-
outcome: ResolveIOSupportV5Outcome;
|
|
338
|
-
lane: ResolveIOSupportV5Lane;
|
|
339
|
-
model?: string;
|
|
340
|
-
threadKey?: string;
|
|
341
|
-
promptTokenEstimate?: number;
|
|
342
|
-
runtimeMs?: number;
|
|
343
|
-
summary: string;
|
|
344
|
-
blocker?: string;
|
|
345
|
-
changedFiles?: string[];
|
|
346
|
-
artifactPaths?: string[];
|
|
347
|
-
diagnosisGate?: ResolveIOSupportDiagnosisGate;
|
|
348
|
-
failureClass?: ResolveIOSupportV5FailureClass | string;
|
|
349
|
-
blockerFingerprint?: string;
|
|
350
|
-
evidenceHash?: string;
|
|
351
|
-
recordedAt: string;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
export interface ResolveIOSupportV5RunnerIncident {
|
|
355
|
-
incidentClass: string;
|
|
356
|
-
summary: string;
|
|
357
|
-
stepType?: ResolveIOSupportV5StepType;
|
|
358
|
-
blockerFingerprint?: string;
|
|
359
|
-
artifactPaths?: string[];
|
|
360
|
-
recordedAt: string;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
export interface ResolveIOSupportV5StateBundle {
|
|
364
|
-
supportWorkflowVersion: 'v5';
|
|
365
|
-
supportV5SupervisorState: ResolveIOSupportV5SupervisorState;
|
|
366
|
-
supportV5DiagnosisGate?: ResolveIOSupportDiagnosisGate;
|
|
367
|
-
supportV5LaneMemory: {
|
|
368
|
-
build: ResolveIOSupportV5LaneMemory;
|
|
369
|
-
qa: ResolveIOSupportV5LaneMemory;
|
|
370
|
-
};
|
|
371
|
-
supportV5StepHistory: ResolveIOSupportV5StepRecord[];
|
|
372
|
-
supportV5Budget: ResolveIOSupportV5Budget;
|
|
373
|
-
supportV5RunnerIncidents: ResolveIOSupportV5RunnerIncident[];
|
|
374
|
-
supportV5MicrotaskLedger: ResolveIOSupportV5Microtask[];
|
|
375
|
-
supportV5ActiveMicrotaskId?: string;
|
|
376
|
-
supportV5ScopeDigest?: string;
|
|
377
|
-
supportV5MicrotaskUsageHistory: ResolveIOSupportV5MicrotaskUsage[];
|
|
378
|
-
supportV5FailureFingerprints?: ResolveIOSupportV5FailureFingerprint[];
|
|
379
|
-
supportV5RecoveryPlan?: ResolveIOAIManagerRecoveryPlan;
|
|
380
|
-
supportV5RecoveryCheckpoint?: ResolveIOAIManagerRecoveryCheckpoint;
|
|
381
|
-
supportV5RecoveryEvidenceProbe?: ResolveIOAIManagerRecoveryEvidenceProbe;
|
|
382
|
-
supportV5RecoveryAction?: ResolveIOAIManagerRecoveryActionPacket;
|
|
383
|
-
supportV5RecoveryDispatchHistory?: ResolveIOAIManagerRecoveryActionDispatchRecord[];
|
|
384
|
-
supportV5RecoveryDirective?: ResolveIOAIManagerRecoveryExecutionDirective;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
export interface ResolveIOSupportV5InitializeInput {
|
|
388
|
-
jobId: string;
|
|
389
|
-
ticketId?: string;
|
|
390
|
-
ticketNumber?: string;
|
|
391
|
-
title?: string;
|
|
392
|
-
description?: string;
|
|
393
|
-
approvedScopeRequirements?: string[];
|
|
394
|
-
approvedScopeHours?: number | null;
|
|
395
|
-
prBranch?: string;
|
|
396
|
-
buildThreadKey?: string;
|
|
397
|
-
qaThreadKey?: string;
|
|
398
|
-
processLease?: ResolveIOSupportV5SupervisorState['processLease'];
|
|
399
|
-
now?: Date | string;
|
|
400
|
-
existing?: Partial<ResolveIOSupportV5StateBundle>;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
export interface ResolveIOSupportV5StepInput {
|
|
404
|
-
microtaskId?: string;
|
|
405
|
-
stepType: ResolveIOSupportV5StepType;
|
|
406
|
-
outcome: ResolveIOSupportV5Outcome;
|
|
407
|
-
lane: ResolveIOSupportV5Lane;
|
|
408
|
-
model?: string;
|
|
409
|
-
threadKey?: string;
|
|
410
|
-
promptTokenEstimate?: number;
|
|
411
|
-
runtimeMs?: number;
|
|
412
|
-
summary?: string;
|
|
413
|
-
blocker?: string;
|
|
414
|
-
changedFiles?: string[];
|
|
415
|
-
artifactPaths?: string[];
|
|
416
|
-
diagnosisGate?: ResolveIOSupportDiagnosisGate;
|
|
417
|
-
failureClass?: ResolveIOSupportV5FailureClass | string;
|
|
418
|
-
evidenceHash?: string;
|
|
419
|
-
activeQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];
|
|
420
|
-
now?: Date | string;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
export interface ResolveIOSupportV5ContinuationDecision {
|
|
424
|
-
action: 'continue' | 'park';
|
|
425
|
-
reason: string;
|
|
426
|
-
nextStep: ResolveIOSupportV5StepType;
|
|
427
|
-
repeatedNoProgressCount: number;
|
|
428
|
-
budgetExceeded: boolean;
|
|
429
|
-
recoveryPlan: ResolveIOAIManagerRecoveryPlan;
|
|
430
|
-
recoveryCheckpoint: ResolveIOAIManagerRecoveryCheckpoint;
|
|
431
|
-
recoveryEvidenceProbe: ResolveIOAIManagerRecoveryEvidenceProbe;
|
|
432
|
-
recoveryAction: ResolveIOAIManagerRecoveryActionPacket;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
function isoNow(value?: Date | string): string {
|
|
436
|
-
if (value instanceof Date) {
|
|
437
|
-
return value.toISOString();
|
|
438
|
-
}
|
|
439
|
-
const parsed = value ? new Date(value) : new Date();
|
|
440
|
-
if (Number.isFinite(parsed.getTime())) {
|
|
441
|
-
return parsed.toISOString();
|
|
442
|
-
}
|
|
443
|
-
return new Date().toISOString();
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
function cleanText(value: any, max = 2000): string {
|
|
447
|
-
return String(value || '').replace(/\s+/g, ' ').trim().slice(0, max);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
function cleanList(values: any, limit = 20, max = 500): string[] {
|
|
451
|
-
if (!Array.isArray(values)) {
|
|
452
|
-
return [];
|
|
453
|
-
}
|
|
454
|
-
const result: string[] = [];
|
|
455
|
-
for (const value of values) {
|
|
456
|
-
const normalized = cleanText(value, max);
|
|
457
|
-
if (normalized && !result.includes(normalized)) {
|
|
458
|
-
result.push(normalized);
|
|
459
|
-
}
|
|
460
|
-
if (result.length >= limit) {
|
|
461
|
-
break;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
return result;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
function cleanObject(value: any): Record<string, any> {
|
|
468
|
-
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
function pickText(source: Record<string, any>, fields: string[], max = 1000): string {
|
|
472
|
-
for (const field of fields) {
|
|
473
|
-
const normalized = cleanText(source?.[field], max);
|
|
474
|
-
if (normalized) {
|
|
475
|
-
return normalized;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
return '';
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
function normalizeIssueClass(value: any): ResolveIOSupportIssueClass | '' {
|
|
482
|
-
const normalized = cleanText(value, 80)
|
|
483
|
-
.toLowerCase()
|
|
484
|
-
.replace(/[\s-]+/g, '_');
|
|
485
|
-
const aliases: Record<string, ResolveIOSupportIssueClass> = {
|
|
486
|
-
no_op: 'no_op_submit',
|
|
487
|
-
no_op_submit: 'no_op_submit',
|
|
488
|
-
submit_noop: 'no_op_submit',
|
|
489
|
-
missing_data: 'missing_wrong_data',
|
|
490
|
-
wrong_data: 'missing_wrong_data',
|
|
491
|
-
missing_wrong_data: 'missing_wrong_data',
|
|
492
|
-
filter_mismatch: 'filter_query_mismatch',
|
|
493
|
-
query_mismatch: 'filter_query_mismatch',
|
|
494
|
-
filter_query_mismatch: 'filter_query_mismatch',
|
|
495
|
-
invoice_pdf_export: 'invoice_pdf_export',
|
|
496
|
-
pdf_export: 'invoice_pdf_export',
|
|
497
|
-
export: 'invoice_pdf_export',
|
|
498
|
-
upload: 'upload_import',
|
|
499
|
-
import: 'upload_import',
|
|
500
|
-
upload_import: 'upload_import',
|
|
501
|
-
route_auth: 'route_auth_hydration',
|
|
502
|
-
auth_hydration: 'route_auth_hydration',
|
|
503
|
-
route_auth_hydration: 'route_auth_hydration',
|
|
504
|
-
slow_query: 'slow_query_performance',
|
|
505
|
-
performance: 'slow_query_performance',
|
|
506
|
-
slow_query_performance: 'slow_query_performance'
|
|
507
|
-
};
|
|
508
|
-
return aliases[normalized] || '';
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
function normalizeReproductionStatus(value: any): ResolveIOSupportDiagnosisIssueCase['reproduction_status'] {
|
|
512
|
-
const normalized = cleanText(value, 80).toLowerCase();
|
|
513
|
-
if (/blocked|unable|cannot/.test(normalized)) {
|
|
514
|
-
return 'blocked';
|
|
515
|
-
}
|
|
516
|
-
if (/classif|triag|inferred/.test(normalized)) {
|
|
517
|
-
return 'classified';
|
|
518
|
-
}
|
|
519
|
-
return 'reproduced';
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
function normalizeSupportDiagnosisEvidence(values: any): ResolveIOSupportDiagnosisEvidence[] {
|
|
523
|
-
const allowed = new Set(['ticket', 'browser', 'mongo', 'log', 'code', 'commit', 'qa', 'other']);
|
|
524
|
-
if (!Array.isArray(values)) {
|
|
525
|
-
const summary = cleanText(values, 1200);
|
|
526
|
-
return summary ? [{ type: 'other', summary }] : [];
|
|
527
|
-
}
|
|
528
|
-
const stringEvidence: ResolveIOSupportDiagnosisEvidence[] = values
|
|
529
|
-
.filter((entry) => typeof entry === 'string')
|
|
530
|
-
.map((entry) => ({
|
|
531
|
-
type: 'other' as const,
|
|
532
|
-
summary: cleanText(entry, 1200)
|
|
533
|
-
}));
|
|
534
|
-
const objectEvidence: ResolveIOSupportDiagnosisEvidence[] = values
|
|
535
|
-
.filter((entry) => entry && typeof entry === 'object' && !Array.isArray(entry))
|
|
536
|
-
.map((entry) => {
|
|
537
|
-
const type = cleanText(entry.type, 80).toLowerCase();
|
|
538
|
-
return {
|
|
539
|
-
type: (allowed.has(type) ? type : 'other') as ResolveIOSupportDiagnosisEvidence['type'],
|
|
540
|
-
summary: cleanText(entry.summary || entry.message || entry.evidence || entry.reason, 1200),
|
|
541
|
-
artifactPath: cleanText(entry.artifactPath || entry.path || entry.file, 500)
|
|
542
|
-
};
|
|
543
|
-
});
|
|
544
|
-
return stringEvidence.concat(objectEvidence)
|
|
545
|
-
.filter((entry) => entry.summary)
|
|
546
|
-
.slice(0, 20);
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
function normalizeSupportDiagnosisHints(values: any): ResolveIOSupportDiagnosisHint[] {
|
|
550
|
-
return (Array.isArray(values) ? values : [])
|
|
551
|
-
.map((entry) => {
|
|
552
|
-
if (typeof entry === 'string') {
|
|
553
|
-
return { reason: cleanText(entry, 500) };
|
|
554
|
-
}
|
|
555
|
-
const value = cleanObject(entry);
|
|
556
|
-
return {
|
|
557
|
-
id: cleanText(value.id || value._id, 160),
|
|
558
|
-
ticketNumber: cleanText(value.ticketNumber || value.ticket_number || value.sourceTicketNumber, 80),
|
|
559
|
-
title: cleanText(value.title || value.summary, 300),
|
|
560
|
-
outcome: cleanText(value.outcome || value.status, 80),
|
|
561
|
-
issueClass: cleanText(value.issueClass || value.issue_class, 80),
|
|
562
|
-
ownerFiles: cleanList(value.ownerFiles || value.owner_files || value.files, 8, 240),
|
|
563
|
-
commitSha: cleanText(value.commitSha || value.commit_sha, 80),
|
|
564
|
-
commitMessage: cleanText(value.commitMessage || value.commit_message, 300),
|
|
565
|
-
reason: cleanText(value.reason || value.matchReason || value.match_reason, 500)
|
|
566
|
-
};
|
|
567
|
-
})
|
|
568
|
-
.filter((entry) => entry.id || entry.ticketNumber || entry.title || entry.reason || entry.commitSha)
|
|
569
|
-
.slice(0, 8);
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
function normalizeOwnerFilePath(value: any): string {
|
|
573
|
-
return cleanText(value, 500)
|
|
574
|
-
.replace(/\\/g, '/')
|
|
575
|
-
.replace(/^\.\/+/, '')
|
|
576
|
-
.replace(/^\/+/, '')
|
|
577
|
-
.replace(/\s+$/g, '');
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
function ownerFileLooksBroad(value: string): boolean {
|
|
581
|
-
const normalized = normalizeOwnerFilePath(value);
|
|
582
|
-
return !normalized
|
|
583
|
-
|| normalized.includes('*')
|
|
584
|
-
|| normalized.endsWith('/')
|
|
585
|
-
|| !/\.[a-z0-9]+$/i.test(normalized)
|
|
586
|
-
|| /^(\.|src|server|angular|client|app|lib|packages?)$/i.test(normalized)
|
|
587
|
-
|| /(^|\/)(node_modules|dist|build|coverage|\.git)(\/|$)/i.test(normalized);
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
function proofPlanLooksRouteOnly(proofPlan: ResolveIOSupportDiagnosisProofPlan): boolean {
|
|
591
|
-
const assertionText = cleanText([
|
|
592
|
-
proofPlan.business_assertion,
|
|
593
|
-
proofPlan.action,
|
|
594
|
-
proofPlan.after,
|
|
595
|
-
proofPlan.data_assertion,
|
|
596
|
-
proofPlan.artifact_expectation
|
|
597
|
-
].filter(Boolean).join(' '), 3000).toLowerCase();
|
|
598
|
-
if (!assertionText) {
|
|
599
|
-
return false;
|
|
600
|
-
}
|
|
601
|
-
const routeOnlySignal = /\b(route|page|screen|dashboard|url|component|shell)\b/.test(assertionText)
|
|
602
|
-
&& /\b(loads?|loaded|renders?|rendered|opens?|opened|visible|visibility|hydrates?|hydrated|screenshot)\b/.test(assertionText);
|
|
603
|
-
const businessSignal = /\b(save|saved|persist|persisted|create|created|update|updated|delete|deleted|filter|filtered|exclude|excluded|include|included|row|rows|record|records|count|counts|total|totals|value|values|data|mongo|query|result|results|invoice|pdf|export|download|upload|import|dropdown|selection|selected|form|submit|submitted|validation|error message|customer|account|user|permission|auth|control|button|status|calculation|performance|duration|latency)\b/.test(assertionText);
|
|
604
|
-
return routeOnlySignal && !businessSignal;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
export function normalizeResolveIOSupportDiagnosisGate(value: any, now?: Date | string): ResolveIOSupportDiagnosisGate | undefined {
|
|
608
|
-
const source = cleanObject(value);
|
|
609
|
-
if (!Object.keys(source).length) {
|
|
610
|
-
return undefined;
|
|
611
|
-
}
|
|
612
|
-
const issueCaseSource = cleanObject(source.issue_case || source.issueCase);
|
|
613
|
-
const hypothesisSource = cleanObject(source.accepted_hypothesis || source.acceptedHypothesis);
|
|
614
|
-
const failingPathSource = cleanObject(source.failing_path || source.failingPath);
|
|
615
|
-
const proofPlanSource = cleanObject(source.proof_plan || source.proofPlan);
|
|
616
|
-
const issueClass = normalizeIssueClass(source.issue_class || source.issueClass);
|
|
617
|
-
const ownerFiles = cleanList(source.owner_files || source.ownerFiles, 20, 500)
|
|
618
|
-
.map(normalizeOwnerFilePath)
|
|
619
|
-
.filter(Boolean);
|
|
620
|
-
const gate: ResolveIOSupportDiagnosisGate = {
|
|
621
|
-
issue_case: {
|
|
622
|
-
customer_complaint: pickText(issueCaseSource, ['customer_complaint', 'customerComplaint', 'complaint', 'request', 'summary'], 1200),
|
|
623
|
-
expected_result: pickText(issueCaseSource, ['expected_result', 'expectedResult', 'expected'], 1000),
|
|
624
|
-
observed_result: pickText(issueCaseSource, ['observed_result', 'observedResult', 'observed', 'actual'], 1000),
|
|
625
|
-
route_module: pickText(issueCaseSource, ['route_module', 'routeModule', 'route', 'module', 'screen'], 500),
|
|
626
|
-
account_customer_context: pickText(issueCaseSource, ['account_customer_context', 'accountCustomerContext', 'account', 'customer', 'user', 'context'], 800),
|
|
627
|
-
reproduction_status: normalizeReproductionStatus(issueCaseSource.reproduction_status || issueCaseSource.reproductionStatus || source.reproduction_status),
|
|
628
|
-
reproduction_blocker: pickText(issueCaseSource, ['reproduction_blocker', 'reproductionBlocker', 'blocked_reason', 'blockedReason'], 1000)
|
|
629
|
-
},
|
|
630
|
-
issue_class: issueClass || 'missing_wrong_data',
|
|
631
|
-
accepted_hypothesis: {
|
|
632
|
-
statement: pickText(hypothesisSource, ['statement', 'hypothesis', 'root_cause', 'rootCause', 'summary'], 1200)
|
|
633
|
-
|| (typeof source.accepted_hypothesis === 'string' ? cleanText(source.accepted_hypothesis, 1200) : ''),
|
|
634
|
-
falsifiable_test: pickText(hypothesisSource, ['falsifiable_test', 'falsifiableTest', 'test', 'proof', 'falsifier'], 1000),
|
|
635
|
-
evidence: cleanList(hypothesisSource.evidence || source.hypothesis_evidence || source.hypothesisEvidence, 10, 800)
|
|
636
|
-
},
|
|
637
|
-
rejected_alternatives: cleanList(source.rejected_alternatives || source.rejectedAlternatives, 10, 700),
|
|
638
|
-
failing_path: {
|
|
639
|
-
frontend: pickText(failingPathSource, ['frontend', 'frontend_path', 'frontendPath', 'eventPath'], 700),
|
|
640
|
-
backend: pickText(failingPathSource, ['backend', 'backend_path', 'backendPath', 'methodPublicationPath'], 700),
|
|
641
|
-
shared_library: pickText(failingPathSource, ['shared_library', 'sharedLibrary', 'library', 'lib'], 700),
|
|
642
|
-
data_query: pickText(failingPathSource, ['data_query', 'dataQuery', 'query'], 700),
|
|
643
|
-
description: pickText(failingPathSource, ['description', 'path', 'summary'], 1200) || cleanText(source.failing_path, 1200)
|
|
644
|
-
},
|
|
645
|
-
owner_files: ownerFiles,
|
|
646
|
-
proof_plan: {
|
|
647
|
-
before: pickText(proofPlanSource, ['before', 'before_state', 'beforeState', 'precondition'], 1000),
|
|
648
|
-
before_state_unavailable_reason: pickText(proofPlanSource, ['before_state_unavailable_reason', 'beforeStateUnavailableReason', 'before_unavailable_reason'], 1000),
|
|
649
|
-
action: pickText(proofPlanSource, ['action', 'browser_action', 'browserAction', 'steps'], 1000),
|
|
650
|
-
after: pickText(proofPlanSource, ['after', 'after_state', 'afterState', 'expected_after'], 1000),
|
|
651
|
-
business_assertion: pickText(proofPlanSource, ['business_assertion', 'businessAssertion', 'assertion'], 1000),
|
|
652
|
-
route: pickText(proofPlanSource, ['route', 'url'], 500),
|
|
653
|
-
data_assertion: pickText(proofPlanSource, ['data_assertion', 'dataAssertion', 'mongo_delta', 'mongoDelta'], 1000),
|
|
654
|
-
artifact_expectation: pickText(proofPlanSource, ['artifact_expectation', 'artifactExpectation', 'artifact', 'screenshot'], 1000)
|
|
655
|
-
},
|
|
656
|
-
similar_tickets: normalizeSupportDiagnosisHints(source.similar_tickets || source.similarTickets),
|
|
657
|
-
similar_commits: normalizeSupportDiagnosisHints(source.similar_commits || source.similarCommits),
|
|
658
|
-
evidence: normalizeSupportDiagnosisEvidence(source.evidence),
|
|
659
|
-
status: (cleanText(source.status, 80).toLowerCase() as ResolveIOSupportDiagnosisGateStatus) || 'incomplete',
|
|
660
|
-
updatedAt: isoNow(now || source.updatedAt || source.updated_at)
|
|
661
|
-
};
|
|
662
|
-
if (!['missing', 'incomplete', 'blocked', 'passed'].includes(gate.status)) {
|
|
663
|
-
gate.status = 'incomplete';
|
|
664
|
-
}
|
|
665
|
-
return gate;
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
export function extractResolveIOSupportDiagnosisGateFromText(value: string, now?: Date | string): ResolveIOSupportDiagnosisGate | undefined {
|
|
669
|
-
const text = String(value || '').trim();
|
|
670
|
-
if (!text) {
|
|
671
|
-
return undefined;
|
|
672
|
-
}
|
|
673
|
-
const candidates: string[] = [];
|
|
674
|
-
const fenced = Array.from(text.matchAll(/```(?:json)?\s*([\s\S]*?)```/gi)).map((match) => match[1]);
|
|
675
|
-
candidates.push(...fenced);
|
|
676
|
-
const jsonBlock = text.match(/\{[\s\S]*\}/);
|
|
677
|
-
if (jsonBlock) {
|
|
678
|
-
candidates.push(jsonBlock[0]);
|
|
679
|
-
}
|
|
680
|
-
for (const candidate of candidates) {
|
|
681
|
-
try {
|
|
682
|
-
const parsed = JSON.parse(candidate);
|
|
683
|
-
const wrapped = parsed?.support_diagnosis_gate || parsed?.supportDiagnosisGate || parsed?.diagnosis_gate || parsed?.diagnosisGate || parsed;
|
|
684
|
-
const normalized = normalizeResolveIOSupportDiagnosisGate(wrapped, now);
|
|
685
|
-
if (normalized) {
|
|
686
|
-
return normalized;
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
catch {
|
|
690
|
-
// Continue trying less exact JSON candidates.
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
return undefined;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
export function validateResolveIOSupportDiagnosisGate(
|
|
697
|
-
value: any,
|
|
698
|
-
options: { maxOwnerFiles?: number } = {}
|
|
699
|
-
): ResolveIOSupportDiagnosisGateValidation {
|
|
700
|
-
const normalized = normalizeResolveIOSupportDiagnosisGate(value);
|
|
701
|
-
if (!normalized) {
|
|
702
|
-
return { valid: false, status: 'missing', blockers: ['SupportDiagnosisGate is missing.'] };
|
|
703
|
-
}
|
|
704
|
-
const blockers: string[] = [];
|
|
705
|
-
const maxOwnerFiles = Math.max(1, Number(options.maxOwnerFiles || 8) || 8);
|
|
706
|
-
if (!normalized.issue_case.customer_complaint) {
|
|
707
|
-
blockers.push('Diagnosis issue_case.customer_complaint is required.');
|
|
708
|
-
}
|
|
709
|
-
if (!normalized.issue_case.expected_result) {
|
|
710
|
-
blockers.push('Diagnosis issue_case.expected_result is required.');
|
|
711
|
-
}
|
|
712
|
-
if (!normalized.issue_case.observed_result) {
|
|
713
|
-
blockers.push('Diagnosis issue_case.observed_result is required.');
|
|
714
|
-
}
|
|
715
|
-
if (!normalized.issue_case.route_module) {
|
|
716
|
-
blockers.push('Diagnosis issue_case.route_module is required.');
|
|
717
|
-
}
|
|
718
|
-
if (!normalized.issue_case.account_customer_context) {
|
|
719
|
-
blockers.push('Diagnosis issue_case.account_customer_context is required.');
|
|
720
|
-
}
|
|
721
|
-
if (normalized.issue_case.reproduction_status === 'blocked' && !normalized.issue_case.reproduction_blocker) {
|
|
722
|
-
blockers.push('Diagnosis blocked reproduction requires issue_case.reproduction_blocker.');
|
|
723
|
-
}
|
|
724
|
-
if (!normalizeIssueClass(normalized.issue_class)) {
|
|
725
|
-
blockers.push('Diagnosis issue_class must be one of the supported issue-class probes.');
|
|
726
|
-
}
|
|
727
|
-
if (!normalized.accepted_hypothesis.statement) {
|
|
728
|
-
blockers.push('Diagnosis accepted_hypothesis.statement is required.');
|
|
729
|
-
}
|
|
730
|
-
if (!normalized.accepted_hypothesis.falsifiable_test) {
|
|
731
|
-
blockers.push('Diagnosis accepted_hypothesis.falsifiable_test is required.');
|
|
732
|
-
}
|
|
733
|
-
if (!normalized.accepted_hypothesis.evidence.length) {
|
|
734
|
-
blockers.push('Diagnosis accepted_hypothesis.evidence must cite proof.');
|
|
735
|
-
}
|
|
736
|
-
if (!normalized.rejected_alternatives.length) {
|
|
737
|
-
blockers.push('Diagnosis rejected_alternatives must include at least one rejected theory.');
|
|
738
|
-
}
|
|
739
|
-
if (!normalized.failing_path.description
|
|
740
|
-
&& !normalized.failing_path.frontend
|
|
741
|
-
&& !normalized.failing_path.backend
|
|
742
|
-
&& !normalized.failing_path.shared_library
|
|
743
|
-
&& !normalized.failing_path.data_query) {
|
|
744
|
-
blockers.push('Diagnosis failing_path must identify frontend, backend, query, shared library, or path description.');
|
|
745
|
-
}
|
|
746
|
-
if (!normalized.owner_files.length) {
|
|
747
|
-
blockers.push('Diagnosis owner_files must contain the small editable file set.');
|
|
748
|
-
}
|
|
749
|
-
if (normalized.owner_files.length > maxOwnerFiles) {
|
|
750
|
-
blockers.push(`Diagnosis owner_files has ${normalized.owner_files.length} entries; maximum is ${maxOwnerFiles}.`);
|
|
751
|
-
}
|
|
752
|
-
const broadFiles = normalized.owner_files.filter(ownerFileLooksBroad);
|
|
753
|
-
if (broadFiles.length) {
|
|
754
|
-
blockers.push(`Diagnosis owner_files contains broad or unsafe path(s): ${broadFiles.join(', ')}.`);
|
|
755
|
-
}
|
|
756
|
-
if (!normalized.proof_plan.before && !normalized.proof_plan.before_state_unavailable_reason) {
|
|
757
|
-
blockers.push('Diagnosis proof_plan.before is required unless proof_plan.before_state_unavailable_reason explains why before-state proof is impossible.');
|
|
758
|
-
}
|
|
759
|
-
if (!normalized.proof_plan.action) {
|
|
760
|
-
blockers.push('Diagnosis proof_plan.action is required.');
|
|
761
|
-
}
|
|
762
|
-
if (!normalized.proof_plan.after) {
|
|
763
|
-
blockers.push('Diagnosis proof_plan.after is required.');
|
|
764
|
-
}
|
|
765
|
-
if (!normalized.proof_plan.business_assertion) {
|
|
766
|
-
blockers.push('Diagnosis proof_plan.business_assertion is required.');
|
|
767
|
-
}
|
|
768
|
-
if (proofPlanLooksRouteOnly(normalized.proof_plan)) {
|
|
769
|
-
blockers.push('Diagnosis proof_plan cannot be route-load, screen-visible, or screenshot-only; it must name the business state/data/control change that proves the issue is fixed.');
|
|
770
|
-
}
|
|
771
|
-
if (!normalized.evidence.length) {
|
|
772
|
-
blockers.push('Diagnosis evidence must include ticket/code/browser/log/Mongo proof.');
|
|
773
|
-
}
|
|
774
|
-
normalized.status = blockers.length ? 'incomplete' : 'passed';
|
|
775
|
-
return {
|
|
776
|
-
valid: blockers.length === 0,
|
|
777
|
-
status: normalized.status,
|
|
778
|
-
blockers,
|
|
779
|
-
normalized
|
|
780
|
-
};
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
export function buildResolveIOSupportIssueClassProbes(value: any): ResolveIOSupportIssueClassProbe[] {
|
|
784
|
-
const validation = validateResolveIOSupportDiagnosisGate(value);
|
|
785
|
-
const gate = validation.normalized || normalizeResolveIOSupportDiagnosisGate(value);
|
|
786
|
-
if (!gate) {
|
|
787
|
-
return [];
|
|
788
|
-
}
|
|
789
|
-
const route = gate.proof_plan.route || gate.issue_case.route_module;
|
|
790
|
-
const proof = gate.proof_plan.business_assertion;
|
|
791
|
-
const common = {
|
|
792
|
-
issue_class: gate.issue_class,
|
|
793
|
-
probe_type: 'issue_class_probe' as ResolveIOSupportV5StepType,
|
|
794
|
-
route,
|
|
795
|
-
blocks_acceptance_without_business_assertion: true
|
|
796
|
-
};
|
|
797
|
-
const map: Record<ResolveIOSupportIssueClass, { action: string; expected: string }> = {
|
|
798
|
-
no_op_submit: {
|
|
799
|
-
action: `Submit the customer action on ${route || 'the affected screen'} and assert a persisted state change or explicit validation message.`,
|
|
800
|
-
expected: proof || 'Before/action/after proof shows the submit is no longer a no-op.'
|
|
801
|
-
},
|
|
802
|
-
missing_wrong_data: {
|
|
803
|
-
action: `Load the named record/list on ${route || 'the affected route'} and compare visible data to the expected persisted source.`,
|
|
804
|
-
expected: proof || 'Visible data and persisted data match the customer expectation.'
|
|
805
|
-
},
|
|
806
|
-
filter_query_mismatch: {
|
|
807
|
-
action: 'Apply the reported filter/query inputs and assert the returned rows/counts match the expected dataset.',
|
|
808
|
-
expected: proof || 'Filter/query output contains the correct included rows and excludes the wrong rows.'
|
|
809
|
-
},
|
|
810
|
-
invoice_pdf_export: {
|
|
811
|
-
action: 'Generate the invoice/PDF/export from the affected route and inspect the downloaded/generated artifact.',
|
|
812
|
-
expected: proof || 'Generated artifact contains the expected customer-visible rows, totals, or fields.'
|
|
813
|
-
},
|
|
814
|
-
upload_import: {
|
|
815
|
-
action: 'Run the upload/import workflow with a representative file and assert parsed plus persisted results.',
|
|
816
|
-
expected: proof || 'Import shows a success result and persisted rows/counts changed as expected.'
|
|
817
|
-
},
|
|
818
|
-
route_auth_hydration: {
|
|
819
|
-
action: 'Open the route as the affected user and assert authenticated hydration reaches the functional screen, not a shell.',
|
|
820
|
-
expected: proof || 'Route hydrates with the required controls/data for the affected account.'
|
|
821
|
-
},
|
|
822
|
-
slow_query_performance: {
|
|
823
|
-
action: 'Run the reported query/workflow with timing/log evidence before and after the fix.',
|
|
824
|
-
expected: proof || 'Performance evidence shows the slow path improved without changing results.'
|
|
825
|
-
}
|
|
826
|
-
};
|
|
827
|
-
const selected = map[gate.issue_class];
|
|
828
|
-
return [{
|
|
829
|
-
...common,
|
|
830
|
-
objective: `Issue-class probe for ${gate.issue_class}: ${gate.issue_case.customer_complaint}`,
|
|
831
|
-
action: selected.action,
|
|
832
|
-
expected_evidence: selected.expected
|
|
833
|
-
}];
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
export function hashResolveIOSupportV5Evidence(value: any): string {
|
|
837
|
-
const raw = typeof value === 'string' ? value : JSON.stringify(value || {});
|
|
838
|
-
const normalized = cleanText(raw, 8000)
|
|
839
|
-
.toLowerCase()
|
|
840
|
-
.replace(/[a-f0-9]{16,}/g, '<id>')
|
|
841
|
-
.replace(/\b\d{2,}\b/g, '<n>');
|
|
842
|
-
let hash = 0;
|
|
843
|
-
for (let index = 0; index < normalized.length; index += 1) {
|
|
844
|
-
hash = ((hash << 5) - hash + normalized.charCodeAt(index)) | 0;
|
|
845
|
-
}
|
|
846
|
-
return `ev-${Math.abs(hash).toString(36) || '0'}`;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
export function decideResolveIOSupportV5RepeatedFailureStop(input: ResolveIOSupportV5RepeatStopInput): ResolveIOSupportV5RepeatStopDecision {
|
|
850
|
-
const failureClass = cleanText(input.failureClass || 'unknown', 80).toLowerCase();
|
|
851
|
-
const blockerFingerprint = fingerprintResolveIOSupportV5Blocker(input.blocker || '');
|
|
852
|
-
const evidenceHash = cleanText(input.evidenceHash, 80) || hashResolveIOSupportV5Evidence(input.evidence || input.blocker || '');
|
|
853
|
-
const limit = Math.max(1, Number(input.limit || 2) || 2);
|
|
854
|
-
if (input.ignoreInfra !== false && /^(infra|compile)$/.test(failureClass)) {
|
|
855
|
-
return {
|
|
856
|
-
shouldStop: false,
|
|
857
|
-
repeatedCount: 0,
|
|
858
|
-
failureClass,
|
|
859
|
-
blockerFingerprint,
|
|
860
|
-
evidenceHash,
|
|
861
|
-
reason: 'support_v5_infra_failures_do_not_count_as_product_repair_loops'
|
|
862
|
-
};
|
|
863
|
-
}
|
|
864
|
-
const latestRecord = (input.history || [])[(input.history || []).length - 1];
|
|
865
|
-
const managerDecision = decideResolveIOAIManagerPolicy({
|
|
866
|
-
history: (input.history || []).map((entry) => ({
|
|
867
|
-
outcome: entry.outcome,
|
|
868
|
-
lane: entry.lane,
|
|
869
|
-
stepType: entry.stepType,
|
|
870
|
-
failureClass: entry.failureClass,
|
|
871
|
-
blocker: entry.blocker || entry.summary,
|
|
872
|
-
blockerFingerprint: entry.blockerFingerprint,
|
|
873
|
-
evidenceHash: entry.evidenceHash,
|
|
874
|
-
changedFiles: entry.changedFiles,
|
|
875
|
-
artifactPaths: entry.artifactPaths,
|
|
876
|
-
summary: entry.summary,
|
|
877
|
-
recordedAt: entry.recordedAt
|
|
878
|
-
})),
|
|
879
|
-
current: {
|
|
880
|
-
outcome: 'needs_repair',
|
|
881
|
-
lane: latestRecord?.lane,
|
|
882
|
-
stepType: latestRecord?.stepType,
|
|
883
|
-
failureClass,
|
|
884
|
-
blocker: input.blocker,
|
|
885
|
-
blockerFingerprint,
|
|
886
|
-
evidenceHash
|
|
887
|
-
},
|
|
888
|
-
maxSameFailureRepeats: limit,
|
|
889
|
-
maxPingPongTransitions: 3,
|
|
890
|
-
infraFailureClasses: input.ignoreInfra !== false ? ['infra', 'compile'] : []
|
|
891
|
-
});
|
|
892
|
-
if (managerDecision.action === 'retry_infra') {
|
|
893
|
-
return {
|
|
894
|
-
shouldStop: false,
|
|
895
|
-
repeatedCount: 0,
|
|
896
|
-
failureClass,
|
|
897
|
-
blockerFingerprint,
|
|
898
|
-
evidenceHash,
|
|
899
|
-
reason: 'support_v5_infra_failures_do_not_count_as_product_repair_loops'
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
if (managerDecision.action === 'park_ping_pong') {
|
|
903
|
-
return {
|
|
904
|
-
shouldStop: true,
|
|
905
|
-
repeatedCount: managerDecision.pingPongCount,
|
|
906
|
-
failureClass,
|
|
907
|
-
blockerFingerprint,
|
|
908
|
-
evidenceHash,
|
|
909
|
-
reason: 'support_v5_ping_pong_failure_loop'
|
|
910
|
-
};
|
|
911
|
-
}
|
|
912
|
-
if (managerDecision.action === 'park_repeated_failure') {
|
|
913
|
-
return {
|
|
914
|
-
shouldStop: true,
|
|
915
|
-
repeatedCount: managerDecision.sameFailureCount,
|
|
916
|
-
failureClass,
|
|
917
|
-
blockerFingerprint,
|
|
918
|
-
evidenceHash,
|
|
919
|
-
reason: 'support_v5_same_failure_class_without_new_evidence'
|
|
920
|
-
};
|
|
921
|
-
}
|
|
922
|
-
let repeatedCount = 0;
|
|
923
|
-
for (let index = (input.history || []).length - 1; index >= 0; index -= 1) {
|
|
924
|
-
const item = input.history[index];
|
|
925
|
-
if (item.outcome === 'pass' || item.outcome === 'ready_for_merge') {
|
|
926
|
-
break;
|
|
927
|
-
}
|
|
928
|
-
const itemFailureClass = cleanText(item.failureClass || 'unknown', 80).toLowerCase();
|
|
929
|
-
const itemBlockerFingerprint = cleanText(item.blockerFingerprint, 80)
|
|
930
|
-
|| fingerprintResolveIOSupportV5Blocker(item.blocker || item.summary || '');
|
|
931
|
-
const itemEvidenceHash = cleanText(item.evidenceHash, 80)
|
|
932
|
-
|| hashResolveIOSupportV5Evidence(item.artifactPaths || item.blocker || item.summary || '');
|
|
933
|
-
if (itemFailureClass !== failureClass || itemBlockerFingerprint !== blockerFingerprint || itemEvidenceHash !== evidenceHash) {
|
|
934
|
-
break;
|
|
935
|
-
}
|
|
936
|
-
repeatedCount += 1;
|
|
937
|
-
}
|
|
938
|
-
return {
|
|
939
|
-
shouldStop: repeatedCount >= limit,
|
|
940
|
-
repeatedCount,
|
|
941
|
-
failureClass,
|
|
942
|
-
blockerFingerprint,
|
|
943
|
-
evidenceHash,
|
|
944
|
-
reason: repeatedCount >= limit
|
|
945
|
-
? 'support_v5_same_failure_class_without_new_evidence'
|
|
946
|
-
: 'support_v5_retry_allowed_new_or_below_repeat_limit'
|
|
947
|
-
};
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
export function changedFilesOutsideResolveIOSupportDiagnosisOwnerFiles(
|
|
951
|
-
diagnosisGate: any,
|
|
952
|
-
changedFiles: any,
|
|
953
|
-
options: { allowTests?: boolean } = {}
|
|
954
|
-
): string[] {
|
|
955
|
-
const validation = validateResolveIOSupportDiagnosisGate(diagnosisGate);
|
|
956
|
-
if (!validation.valid || !validation.normalized) {
|
|
957
|
-
return cleanList(changedFiles, 80, 500);
|
|
958
|
-
}
|
|
959
|
-
const owners = new Set(validation.normalized.owner_files.map(normalizeOwnerFilePath));
|
|
960
|
-
return cleanList(changedFiles, 120, 500)
|
|
961
|
-
.map(normalizeOwnerFilePath)
|
|
962
|
-
.filter((filePath) => {
|
|
963
|
-
if (!filePath) {
|
|
964
|
-
return false;
|
|
965
|
-
}
|
|
966
|
-
if (owners.has(filePath)) {
|
|
967
|
-
return false;
|
|
968
|
-
}
|
|
969
|
-
if (options.allowTests && /(^|\/)(tests?|spec|__tests__)(\/|$)|\.(?:spec|test)\.[jt]sx?$/i.test(filePath)) {
|
|
970
|
-
return false;
|
|
971
|
-
}
|
|
972
|
-
return true;
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
export function decideResolveIOSupportV5RepairGate(input: ResolveIOSupportV5RepairGateInput): ResolveIOSupportV5RepairGateDecision {
|
|
977
|
-
const activeStepType = cleanText(input.activeStepType, 80);
|
|
978
|
-
const failureClass = cleanText(input.failureClass, 80).toLowerCase();
|
|
979
|
-
const diagnosisValidation = validateResolveIOSupportDiagnosisGate(input.diagnosisGate, {
|
|
980
|
-
maxOwnerFiles: input.maxOwnerFiles
|
|
981
|
-
});
|
|
982
|
-
const ownerFiles = diagnosisValidation.normalized?.owner_files || [];
|
|
983
|
-
const outsideOwnerFiles = changedFilesOutsideResolveIOSupportDiagnosisOwnerFiles(
|
|
984
|
-
diagnosisValidation.normalized || input.diagnosisGate,
|
|
985
|
-
input.changedFiles,
|
|
986
|
-
{ allowTests: input.allowTestsOutsideOwnerFiles === true }
|
|
987
|
-
);
|
|
988
|
-
const repeatedFailure = input.history?.length ? decideResolveIOSupportV5RepeatedFailureStop({
|
|
989
|
-
history: input.history,
|
|
990
|
-
failureClass,
|
|
991
|
-
blocker: input.blocker,
|
|
992
|
-
evidence: input.evidence,
|
|
993
|
-
evidenceHash: input.evidenceHash,
|
|
994
|
-
limit: Math.max(1, Number(input.maxRepeatedNoProgress || 2) || 2),
|
|
995
|
-
ignoreInfra: true
|
|
996
|
-
}) : undefined;
|
|
997
|
-
const recoveryPlanFor = (
|
|
998
|
-
action: string,
|
|
999
|
-
reason: string,
|
|
1000
|
-
recoveryFailureClass = failureClass || 'unknown',
|
|
1001
|
-
productRepairFailure = false
|
|
1002
|
-
): ResolveIOAIManagerRecoveryPlan => buildResolveIOAIManagerRecoveryPlan({
|
|
1003
|
-
action,
|
|
1004
|
-
reason,
|
|
1005
|
-
failureClass: recoveryFailureClass,
|
|
1006
|
-
lane: 'build',
|
|
1007
|
-
stepType: activeStepType || 'build_repair',
|
|
1008
|
-
blocker: input.blocker || (diagnosisValidation.blockers || []).join(' | '),
|
|
1009
|
-
changedFiles: cleanList(input.changedFiles, 40, 500),
|
|
1010
|
-
maxSameFailureRepeats: Math.max(1, Number(input.maxRepeatedNoProgress || 2) || 2),
|
|
1011
|
-
productRepairFailure
|
|
1012
|
-
});
|
|
1013
|
-
const recoveryCheckpointFor = (
|
|
1014
|
-
recoveryPlan: ResolveIOAIManagerRecoveryPlan
|
|
1015
|
-
): ResolveIOAIManagerRecoveryCheckpoint => buildResolveIOAIManagerRecoveryCheckpoint({
|
|
1016
|
-
plan: recoveryPlan,
|
|
1017
|
-
current: {
|
|
1018
|
-
lane: 'build',
|
|
1019
|
-
stepType: activeStepType || 'build_repair',
|
|
1020
|
-
failureClass: failureClass || 'unknown',
|
|
1021
|
-
blocker: input.blocker || (diagnosisValidation.blockers || []).join(' | '),
|
|
1022
|
-
evidenceHash: input.evidenceHash,
|
|
1023
|
-
changedFiles: cleanList(input.changedFiles, 40, 500),
|
|
1024
|
-
summary: input.blocker
|
|
1025
|
-
}
|
|
1026
|
-
});
|
|
1027
|
-
const recoveryFieldsFor = (
|
|
1028
|
-
recoveryPlan: ResolveIOAIManagerRecoveryPlan
|
|
1029
|
-
): Pick<ResolveIOSupportV5RepairGateDecision, 'recoveryPlan' | 'recoveryCheckpoint' | 'recoveryEvidenceProbe' | 'recoveryAction'> => {
|
|
1030
|
-
const recoveryCheckpoint = recoveryCheckpointFor(recoveryPlan);
|
|
1031
|
-
const recoveryEvidenceProbe = buildResolveIOAIManagerRecoveryEvidenceProbe({
|
|
1032
|
-
checkpoint: recoveryCheckpoint,
|
|
1033
|
-
current: {
|
|
1034
|
-
lane: 'build',
|
|
1035
|
-
stepType: activeStepType || 'build_repair',
|
|
1036
|
-
failureClass: failureClass || 'unknown',
|
|
1037
|
-
blocker: input.blocker || (diagnosisValidation.blockers || []).join(' | '),
|
|
1038
|
-
evidenceHash: input.evidenceHash,
|
|
1039
|
-
changedFiles: cleanList(input.changedFiles, 40, 500),
|
|
1040
|
-
summary: input.blocker
|
|
1041
|
-
}
|
|
1042
|
-
});
|
|
1043
|
-
const current = {
|
|
1044
|
-
lane: 'build',
|
|
1045
|
-
stepType: activeStepType || 'build_repair',
|
|
1046
|
-
failureClass: failureClass || 'unknown',
|
|
1047
|
-
blocker: input.blocker || (diagnosisValidation.blockers || []).join(' | '),
|
|
1048
|
-
evidenceHash: input.evidenceHash,
|
|
1049
|
-
changedFiles: cleanList(input.changedFiles, 40, 500),
|
|
1050
|
-
summary: input.blocker
|
|
1051
|
-
};
|
|
1052
|
-
return {
|
|
1053
|
-
recoveryPlan,
|
|
1054
|
-
recoveryCheckpoint,
|
|
1055
|
-
recoveryEvidenceProbe,
|
|
1056
|
-
recoveryAction: buildResolveIOAIManagerRecoveryActionPacket({
|
|
1057
|
-
plan: recoveryPlan,
|
|
1058
|
-
checkpoint: recoveryCheckpoint,
|
|
1059
|
-
probe: recoveryEvidenceProbe,
|
|
1060
|
-
current
|
|
1061
|
-
})
|
|
1062
|
-
};
|
|
1063
|
-
};
|
|
1064
|
-
if (repeatedFailure?.shouldStop) {
|
|
1065
|
-
const recoveryPlan = recoveryPlanFor('park_repeated_failure', repeatedFailure.reason, repeatedFailure.failureClass, true);
|
|
1066
|
-
return {
|
|
1067
|
-
action: 'park_repeated_failure',
|
|
1068
|
-
canEditProductCode: false,
|
|
1069
|
-
blockers: [repeatedFailure.reason],
|
|
1070
|
-
ownerFiles,
|
|
1071
|
-
issueClass: diagnosisValidation.normalized?.issue_class,
|
|
1072
|
-
proofPlan: diagnosisValidation.normalized?.proof_plan,
|
|
1073
|
-
outsideOwnerFiles,
|
|
1074
|
-
repeatedFailure,
|
|
1075
|
-
diagnosisValidation,
|
|
1076
|
-
...recoveryFieldsFor(recoveryPlan)
|
|
1077
|
-
};
|
|
1078
|
-
}
|
|
1079
|
-
if (failureClass === 'infra' || failureClass === 'compile') {
|
|
1080
|
-
const recoveryPlan = recoveryPlanFor('retry_infra', 'support_v5_infra_or_compile_repair_required', failureClass, false);
|
|
1081
|
-
return {
|
|
1082
|
-
action: 'infra_repair_only',
|
|
1083
|
-
canEditProductCode: false,
|
|
1084
|
-
blockers: ['Infra/compile/Puppeteer/startup failures must be repaired in the harness lane before product-code repair.'],
|
|
1085
|
-
ownerFiles,
|
|
1086
|
-
issueClass: diagnosisValidation.normalized?.issue_class,
|
|
1087
|
-
proofPlan: diagnosisValidation.normalized?.proof_plan,
|
|
1088
|
-
outsideOwnerFiles,
|
|
1089
|
-
repeatedFailure,
|
|
1090
|
-
diagnosisValidation,
|
|
1091
|
-
...recoveryFieldsFor(recoveryPlan)
|
|
1092
|
-
};
|
|
1093
|
-
}
|
|
1094
|
-
if (activeStepType === 'diagnosis_gate' || !diagnosisValidation.valid) {
|
|
1095
|
-
const recoveryPlan = recoveryPlanFor('continue', 'support_v5_diagnosis_gate_required', 'diagnosis', false);
|
|
1096
|
-
return {
|
|
1097
|
-
action: 'diagnose_only',
|
|
1098
|
-
canEditProductCode: false,
|
|
1099
|
-
blockers: diagnosisValidation.blockers.length
|
|
1100
|
-
? diagnosisValidation.blockers
|
|
1101
|
-
: ['SupportDiagnosisGate is required before product-code repair.'],
|
|
1102
|
-
ownerFiles,
|
|
1103
|
-
issueClass: diagnosisValidation.normalized?.issue_class,
|
|
1104
|
-
proofPlan: diagnosisValidation.normalized?.proof_plan,
|
|
1105
|
-
outsideOwnerFiles,
|
|
1106
|
-
repeatedFailure,
|
|
1107
|
-
diagnosisValidation,
|
|
1108
|
-
...recoveryFieldsFor(recoveryPlan)
|
|
1109
|
-
};
|
|
1110
|
-
}
|
|
1111
|
-
if (outsideOwnerFiles.length) {
|
|
1112
|
-
const recoveryPlan = recoveryPlanFor('continue', 'support_v5_out_of_scope_requires_diagnosis_revision', 'owner_scope', false);
|
|
1113
|
-
return {
|
|
1114
|
-
action: 'reject_out_of_scope',
|
|
1115
|
-
canEditProductCode: false,
|
|
1116
|
-
blockers: [`Changed files outside diagnosis owner_files; revise diagnosis with new evidence before broadening edits: ${outsideOwnerFiles.join(', ')}`],
|
|
1117
|
-
ownerFiles,
|
|
1118
|
-
issueClass: diagnosisValidation.normalized?.issue_class,
|
|
1119
|
-
proofPlan: diagnosisValidation.normalized?.proof_plan,
|
|
1120
|
-
outsideOwnerFiles,
|
|
1121
|
-
repeatedFailure,
|
|
1122
|
-
diagnosisValidation,
|
|
1123
|
-
...recoveryFieldsFor(recoveryPlan)
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
const recoveryPlan = recoveryPlanFor('continue', 'support_v5_product_repair_allowed_after_diagnosis', failureClass || 'product_code', true);
|
|
1127
|
-
return {
|
|
1128
|
-
action: 'allow_product_repair',
|
|
1129
|
-
canEditProductCode: true,
|
|
1130
|
-
blockers: [],
|
|
1131
|
-
ownerFiles,
|
|
1132
|
-
issueClass: diagnosisValidation.normalized?.issue_class,
|
|
1133
|
-
proofPlan: diagnosisValidation.normalized?.proof_plan,
|
|
1134
|
-
outsideOwnerFiles,
|
|
1135
|
-
repeatedFailure,
|
|
1136
|
-
diagnosisValidation,
|
|
1137
|
-
...recoveryFieldsFor(recoveryPlan)
|
|
1138
|
-
};
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
export function applyResolveIOSupportDiagnosisGateToMicrotasks(
|
|
1142
|
-
bundle: ResolveIOSupportV5StateBundle,
|
|
1143
|
-
diagnosisGate: any
|
|
1144
|
-
): ResolveIOSupportV5StateBundle {
|
|
1145
|
-
const validation = validateResolveIOSupportDiagnosisGate(diagnosisGate);
|
|
1146
|
-
const gate = validation.normalized;
|
|
1147
|
-
if (!gate) {
|
|
1148
|
-
return bundle;
|
|
1149
|
-
}
|
|
1150
|
-
const ownerFiles = gate.owner_files;
|
|
1151
|
-
const probes = buildResolveIOSupportIssueClassProbes(gate);
|
|
1152
|
-
const now = isoNow();
|
|
1153
|
-
const diagnosisMicrotaskId = (bundle.supportV5MicrotaskLedger || [])
|
|
1154
|
-
.find((task) => task.type === 'diagnosis_gate')?.microtaskId
|
|
1155
|
-
|| stableIdFromText('diagnosis', `Root-cause-first diagnosis gate for: ${cleanText(bundle.supportV5ScopeDigest || gate.issue_case.customer_complaint, 360) || 'support ticket'}`);
|
|
1156
|
-
const ledger = (bundle.supportV5MicrotaskLedger || []).map((task) => {
|
|
1157
|
-
if (task.type === 'diagnosis_gate') {
|
|
1158
|
-
return {
|
|
1159
|
-
...task,
|
|
1160
|
-
status: validation.valid ? 'pass' as ResolveIOSupportV5MicrotaskStatus : 'needs_repair' as ResolveIOSupportV5MicrotaskStatus,
|
|
1161
|
-
blocker: validation.valid ? '' : validation.blockers.join(' | '),
|
|
1162
|
-
updatedAt: now
|
|
1163
|
-
};
|
|
1164
|
-
}
|
|
1165
|
-
if (task.lane === 'build' && /repair|product_repair|build_repair/i.test(String(task.type || ''))) {
|
|
1166
|
-
return {
|
|
1167
|
-
...task,
|
|
1168
|
-
targetFiles: ownerFiles,
|
|
1169
|
-
contextRefs: Array.from(new Set([...(task.contextRefs || []), 'supportV5DiagnosisGate', 'owner_files'])),
|
|
1170
|
-
selfGate: `Repair only the diagnosed owner files unless you revise the diagnosis with new evidence. Owner files: ${ownerFiles.join(', ')}.`,
|
|
1171
|
-
acceptanceProof: gate.proof_plan.business_assertion,
|
|
1172
|
-
dependsOn: Array.from(new Set([...(task.dependsOn || []), diagnosisMicrotaskId])),
|
|
1173
|
-
updatedAt: now
|
|
1174
|
-
};
|
|
1175
|
-
}
|
|
1176
|
-
if (task.lane === 'qa' && task.type === 'qa_row') {
|
|
1177
|
-
return {
|
|
1178
|
-
...task,
|
|
1179
|
-
contextRefs: Array.from(new Set([...(task.contextRefs || []), 'supportV5DiagnosisGate', 'proof_plan'])),
|
|
1180
|
-
selfGate: probes[0]?.action || task.selfGate,
|
|
1181
|
-
acceptanceProof: gate.proof_plan.business_assertion || task.acceptanceProof,
|
|
1182
|
-
targetFiles: ownerFiles,
|
|
1183
|
-
updatedAt: now
|
|
1184
|
-
};
|
|
1185
|
-
}
|
|
1186
|
-
return task;
|
|
1187
|
-
});
|
|
1188
|
-
const nextActive = selectResolveIOSupportV5ActiveMicrotask(ledger, bundle.supportV5ActiveMicrotaskId);
|
|
1189
|
-
return {
|
|
1190
|
-
...bundle,
|
|
1191
|
-
supportV5DiagnosisGate: gate,
|
|
1192
|
-
supportV5MicrotaskLedger: ledger,
|
|
1193
|
-
supportV5ActiveMicrotaskId: nextActive?.microtaskId,
|
|
1194
|
-
supportV5LaneMemory: {
|
|
1195
|
-
...bundle.supportV5LaneMemory,
|
|
1196
|
-
build: {
|
|
1197
|
-
...bundle.supportV5LaneMemory.build,
|
|
1198
|
-
changedFiles: ownerFiles,
|
|
1199
|
-
scopeSummary: [
|
|
1200
|
-
bundle.supportV5LaneMemory.build.scopeSummary,
|
|
1201
|
-
`Diagnosis issue class: ${gate.issue_class}`,
|
|
1202
|
-
`Accepted hypothesis: ${gate.accepted_hypothesis.statement}`,
|
|
1203
|
-
`Owner files: ${ownerFiles.join(', ')}`
|
|
1204
|
-
].filter(Boolean).join(' | '),
|
|
1205
|
-
updatedAt: now
|
|
1206
|
-
},
|
|
1207
|
-
qa: {
|
|
1208
|
-
...bundle.supportV5LaneMemory.qa,
|
|
1209
|
-
activeQaRow: {
|
|
1210
|
-
workflow: gate.proof_plan.business_assertion,
|
|
1211
|
-
route: gate.proof_plan.route || gate.issue_case.route_module,
|
|
1212
|
-
assertion: gate.proof_plan.after,
|
|
1213
|
-
status: 'pending'
|
|
1214
|
-
},
|
|
1215
|
-
updatedAt: now
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
};
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
function stableIdFromText(prefix: string, value: string): string {
|
|
1222
|
-
const text = cleanText(value, 2000).toLowerCase();
|
|
1223
|
-
let hash = 0;
|
|
1224
|
-
for (let index = 0; index < text.length; index += 1) {
|
|
1225
|
-
hash = ((hash << 5) - hash + text.charCodeAt(index)) | 0;
|
|
1226
|
-
}
|
|
1227
|
-
return `${prefix}-${Math.abs(hash).toString(36) || '0'}`;
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
|
-
function estimateTextTokens(value: string): number {
|
|
1231
|
-
const text = String(value || '');
|
|
1232
|
-
if (!text) {
|
|
1233
|
-
return 0;
|
|
1234
|
-
}
|
|
1235
|
-
return Math.max(1, Math.ceil(text.length / 4));
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
export function fingerprintResolveIOSupportV5Blocker(value: any): string {
|
|
1239
|
-
const text = cleanText(value, 4000)
|
|
1240
|
-
.toLowerCase()
|
|
1241
|
-
.replace(/[a-f0-9]{16,}/g, '<id>')
|
|
1242
|
-
.replace(/\b\d{2,}\b/g, '<n>')
|
|
1243
|
-
.replace(/\bline\s+<n>\b/g, 'line <n>');
|
|
1244
|
-
let hash = 0;
|
|
1245
|
-
for (let index = 0; index < text.length; index += 1) {
|
|
1246
|
-
hash = ((hash << 5) - hash + text.charCodeAt(index)) | 0;
|
|
1247
|
-
}
|
|
1248
|
-
return `v5-${Math.abs(hash).toString(36)}`;
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
export function buildResolveIOSupportV5Budget(existing?: Partial<ResolveIOSupportV5Budget>): ResolveIOSupportV5Budget {
|
|
1252
|
-
return {
|
|
1253
|
-
maxPromptTokensPerNonInitialStep: Number(existing?.maxPromptTokensPerNonInitialStep || 1800),
|
|
1254
|
-
maxLoopsPerTicket: Number(existing?.maxLoopsPerTicket || 24),
|
|
1255
|
-
maxRepeatedNoProgress: Number(existing?.maxRepeatedNoProgress || 2),
|
|
1256
|
-
maxRuntimeMinutesPerLoop: Number(existing?.maxRuntimeMinutesPerLoop || 15),
|
|
1257
|
-
totalPromptTokenEstimate: Number(existing?.totalPromptTokenEstimate || 0),
|
|
1258
|
-
totalRuntimeMs: Number(existing?.totalRuntimeMs || 0),
|
|
1259
|
-
loopCount: Number(existing?.loopCount || 0)
|
|
1260
|
-
};
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
export function buildResolveIOSupportV5PromptBudget(existing?: Partial<ResolveIOSupportV5PromptBudget>): ResolveIOSupportV5PromptBudget {
|
|
1264
|
-
return {
|
|
1265
|
-
initialPlannerCap: Number(existing?.initialPlannerCap || 6000),
|
|
1266
|
-
buildMicrotaskCap: Number(existing?.buildMicrotaskCap || 1800),
|
|
1267
|
-
buildMicrotaskHardCap: Number(existing?.buildMicrotaskHardCap || 2500),
|
|
1268
|
-
qaMicrotaskCap: Number(existing?.qaMicrotaskCap || 1500),
|
|
1269
|
-
qaMicrotaskHardCap: Number(existing?.qaMicrotaskHardCap || 2200),
|
|
1270
|
-
repairMicrotaskCap: Number(existing?.repairMicrotaskCap || 1200),
|
|
1271
|
-
repairMicrotaskHardCap: Number(existing?.repairMicrotaskHardCap || 1800)
|
|
1272
|
-
};
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
export function buildResolveIOSupportV5ScopeDigest(input: {
|
|
1276
|
-
goal?: string;
|
|
1277
|
-
approvedScope?: string | string[];
|
|
1278
|
-
prBranch?: string;
|
|
1279
|
-
maxTokens?: number;
|
|
1280
|
-
}): string {
|
|
1281
|
-
const scope = Array.isArray(input.approvedScope)
|
|
1282
|
-
? cleanList(input.approvedScope, 30, 220).join(' | ')
|
|
1283
|
-
: cleanText(input.approvedScope, 4000);
|
|
1284
|
-
const raw = [
|
|
1285
|
-
input.goal ? `Goal: ${cleanText(input.goal, 300)}` : '',
|
|
1286
|
-
scope ? `Approved scope: ${scope}` : '',
|
|
1287
|
-
input.prBranch ? `PR branch: ${cleanText(input.prBranch, 160)}` : ''
|
|
1288
|
-
].filter(Boolean).join('\n');
|
|
1289
|
-
const maxChars = Math.max(400, Math.floor(Number(input.maxTokens || 1000) * 4));
|
|
1290
|
-
return raw.slice(0, maxChars);
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1293
|
-
export function buildResolveIOSupportV5MicrotaskLedger(input: {
|
|
1294
|
-
scopeDigest: string;
|
|
1295
|
-
requirements?: string[];
|
|
1296
|
-
buildThreadKey: string;
|
|
1297
|
-
qaThreadKey: string;
|
|
1298
|
-
now?: Date | string;
|
|
1299
|
-
existing?: ResolveIOSupportV5Microtask[];
|
|
1300
|
-
}): ResolveIOSupportV5Microtask[] {
|
|
1301
|
-
const existing = Array.isArray(input.existing) ? input.existing : [];
|
|
1302
|
-
const completedByObjective = new Map<string, ResolveIOSupportV5Microtask>();
|
|
1303
|
-
for (const task of existing) {
|
|
1304
|
-
if (task && (task.status === 'pass' || task.status === 'parked')) {
|
|
1305
|
-
completedByObjective.set(cleanText(task.objective, 500).toLowerCase(), task);
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
const now = isoNow(input.now);
|
|
1309
|
-
const requirements = cleanList(input.requirements, 30, 240);
|
|
1310
|
-
const sourceRequirements = requirements.length
|
|
1311
|
-
? requirements
|
|
1312
|
-
: cleanText(input.scopeDigest, 1000).split(/\s+\|\s+|\r?\n/g).map((line) => line.trim()).filter(Boolean).slice(0, 12);
|
|
1313
|
-
const ledger: ResolveIOSupportV5Microtask[] = [];
|
|
1314
|
-
const diagnosisObjective = `Root-cause-first diagnosis gate for: ${cleanText(input.scopeDigest, 360) || 'support ticket'}`;
|
|
1315
|
-
const diagnosisId = stableIdFromText('diagnosis', diagnosisObjective);
|
|
1316
|
-
const existingDiagnosis = existing.find((task) => task?.type === 'diagnosis_gate' || task?.microtaskId === diagnosisId);
|
|
1317
|
-
ledger.push(existingDiagnosis && (existingDiagnosis.status === 'pass' || existingDiagnosis.status === 'parked') ? existingDiagnosis : {
|
|
1318
|
-
microtaskId: diagnosisId,
|
|
1319
|
-
lane: 'build',
|
|
1320
|
-
type: 'diagnosis_gate',
|
|
1321
|
-
status: existingDiagnosis?.status || 'pending',
|
|
1322
|
-
objective: diagnosisObjective,
|
|
1323
|
-
targetFiles: [],
|
|
1324
|
-
contextRefs: ['scope_digest', 'support_context', 'similar_tickets', 'similar_commits'],
|
|
1325
|
-
selfGate: 'Read-only diagnosis only: reproduce or explicitly classify the issue, accept one falsifiable root-cause hypothesis, reject alternatives, identify the failing path, cap owner_files, and define before/action/after business proof.',
|
|
1326
|
-
acceptanceProof: 'Valid ResolveIOSupportDiagnosisGate JSON with issue_case, issue_class, accepted_hypothesis, rejected_alternatives, failing_path, owner_files, proof_plan, evidence, and status=passed.',
|
|
1327
|
-
threadKey: input.buildThreadKey,
|
|
1328
|
-
promptTokenEstimate: existingDiagnosis?.promptTokenEstimate,
|
|
1329
|
-
attempts: existingDiagnosis?.attempts || 0,
|
|
1330
|
-
dependsOn: [],
|
|
1331
|
-
parentScopeId: stableIdFromText('scope', diagnosisObjective),
|
|
1332
|
-
blocker: existingDiagnosis?.blocker,
|
|
1333
|
-
createdAt: existingDiagnosis?.createdAt || now,
|
|
1334
|
-
updatedAt: existingDiagnosis?.updatedAt || now
|
|
1335
|
-
});
|
|
1336
|
-
sourceRequirements.forEach((requirement, index) => {
|
|
1337
|
-
const objective = cleanText(requirement, 240);
|
|
1338
|
-
if (!objective) {
|
|
1339
|
-
return;
|
|
1340
|
-
}
|
|
1341
|
-
const existingCompleted = completedByObjective.get(objective.toLowerCase());
|
|
1342
|
-
const buildId = stableIdFromText(`build-${index + 1}`, objective);
|
|
1343
|
-
const qaId = stableIdFromText(`qa-${index + 1}`, objective);
|
|
1344
|
-
ledger.push(existingCompleted && existingCompleted.lane === 'build' ? existingCompleted : {
|
|
1345
|
-
microtaskId: buildId,
|
|
1346
|
-
lane: 'build',
|
|
1347
|
-
type: 'build_repair',
|
|
1348
|
-
status: 'pending',
|
|
1349
|
-
objective,
|
|
1350
|
-
targetFiles: [],
|
|
1351
|
-
contextRefs: ['scope_digest'],
|
|
1352
|
-
selfGate: 'Run the smallest compile/type/unit check that proves this one behavior.',
|
|
1353
|
-
acceptanceProof: 'Concrete code/data proof for this behavior, with changed files listed.',
|
|
1354
|
-
threadKey: input.buildThreadKey,
|
|
1355
|
-
attempts: 0,
|
|
1356
|
-
dependsOn: [diagnosisId],
|
|
1357
|
-
parentScopeId: stableIdFromText('scope', objective),
|
|
1358
|
-
createdAt: now,
|
|
1359
|
-
updatedAt: now
|
|
1360
|
-
});
|
|
1361
|
-
ledger.push({
|
|
1362
|
-
microtaskId: qaId,
|
|
1363
|
-
lane: 'qa',
|
|
1364
|
-
type: 'qa_row',
|
|
1365
|
-
status: 'pending',
|
|
1366
|
-
objective: `QA proof for: ${objective}`,
|
|
1367
|
-
targetFiles: [],
|
|
1368
|
-
contextRefs: ['scope_digest', buildId],
|
|
1369
|
-
selfGate: 'Drive this one customer-facing workflow row in browser/localhost and capture one captioned proof artifact.',
|
|
1370
|
-
acceptanceProof: 'QA matrix row pass with route/data assertion, screenshot/caption artifact, and persisted before/after row/count/value proof for data-changing workflows.',
|
|
1371
|
-
threadKey: input.qaThreadKey,
|
|
1372
|
-
attempts: 0,
|
|
1373
|
-
dependsOn: [diagnosisId, buildId],
|
|
1374
|
-
parentScopeId: stableIdFromText('scope', objective),
|
|
1375
|
-
createdAt: now,
|
|
1376
|
-
updatedAt: now
|
|
1377
|
-
});
|
|
1378
|
-
});
|
|
1379
|
-
return ledger.length ? ledger : existing.slice(-80);
|
|
1380
|
-
}
|
|
1381
|
-
|
|
1382
|
-
export function selectResolveIOSupportV5ActiveMicrotask(
|
|
1383
|
-
ledger: ResolveIOSupportV5Microtask[] = [],
|
|
1384
|
-
preferredId?: string
|
|
1385
|
-
): ResolveIOSupportV5Microtask | undefined {
|
|
1386
|
-
const byPreferred = preferredId ? ledger.find((task) => task.microtaskId === preferredId && !['pass', 'parked'].includes(task.status)) : undefined;
|
|
1387
|
-
if (byPreferred) {
|
|
1388
|
-
return byPreferred;
|
|
1389
|
-
}
|
|
1390
|
-
return ledger.find((task) => task.status === 'needs_repair')
|
|
1391
|
-
|| ledger.find((task) => task.status === 'in_progress')
|
|
1392
|
-
|| ledger.find((task) => task.lane === 'build' && /repair/i.test(String(task.type || '')) && task.status === 'pending')
|
|
1393
|
-
|| ledger.find((task) => task.status === 'pending')
|
|
1394
|
-
|| ledger.find((task) => task.status === 'blocked');
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
export function initializeResolveIOSupportV5State(input: ResolveIOSupportV5InitializeInput): ResolveIOSupportV5StateBundle {
|
|
1398
|
-
const now = isoNow(input.now);
|
|
1399
|
-
const existing = input.existing || {};
|
|
1400
|
-
const existingSupervisor = existing.supportV5SupervisorState;
|
|
1401
|
-
const existingLaneMemory = existing.supportV5LaneMemory || {} as ResolveIOSupportV5StateBundle['supportV5LaneMemory'];
|
|
1402
|
-
const scope = cleanList(input.approvedScopeRequirements, 24, 240).join(' | ')
|
|
1403
|
-
|| cleanText(input.description, 1000)
|
|
1404
|
-
|| cleanText(input.title, 300);
|
|
1405
|
-
const ticketLabel = cleanText(input.ticketNumber || input.ticketId || input.jobId, 120);
|
|
1406
|
-
const buildThreadKey = cleanText(input.buildThreadKey || existingLaneMemory.build?.threadKey || `support:${input.ticketId || input.jobId}:job:${input.jobId}:build`, 240);
|
|
1407
|
-
const qaThreadKey = cleanText(input.qaThreadKey || existingLaneMemory.qa?.threadKey || `support:${input.ticketId || input.jobId}:job:${input.jobId}:qa`, 240);
|
|
1408
|
-
const budget = buildResolveIOSupportV5Budget(existing.supportV5Budget);
|
|
1409
|
-
const existingDiagnosisGate = normalizeResolveIOSupportDiagnosisGate((existing as any).supportV5DiagnosisGate);
|
|
1410
|
-
const diagnosisValidation = validateResolveIOSupportDiagnosisGate(existingDiagnosisGate);
|
|
1411
|
-
const scopeDigest = cleanText((existing as any).supportV5ScopeDigest, 4000) || buildResolveIOSupportV5ScopeDigest({
|
|
1412
|
-
goal: existingSupervisor?.currentGoal || `Resolve support ticket ${ticketLabel}`,
|
|
1413
|
-
approvedScope: scope,
|
|
1414
|
-
prBranch: input.prBranch || existingSupervisor?.prBranch || ''
|
|
1415
|
-
});
|
|
1416
|
-
const ledger = buildResolveIOSupportV5MicrotaskLedger({
|
|
1417
|
-
scopeDigest,
|
|
1418
|
-
requirements: cleanList(input.approvedScopeRequirements, 30, 240),
|
|
1419
|
-
buildThreadKey,
|
|
1420
|
-
qaThreadKey,
|
|
1421
|
-
now,
|
|
1422
|
-
existing: (existing as any).supportV5MicrotaskLedger
|
|
1423
|
-
});
|
|
1424
|
-
const activeMicrotask = selectResolveIOSupportV5ActiveMicrotask(ledger, (existing as any).supportV5ActiveMicrotaskId);
|
|
1425
|
-
const initialized: ResolveIOSupportV5StateBundle = {
|
|
1426
|
-
supportWorkflowVersion: 'v5',
|
|
1427
|
-
supportV5SupervisorState: {
|
|
1428
|
-
version: 'v5',
|
|
1429
|
-
status: existingSupervisor?.status || 'active',
|
|
1430
|
-
currentGoal: existingSupervisor?.currentGoal || `Resolve support ticket ${ticketLabel}`,
|
|
1431
|
-
approvedScope: existingSupervisor?.approvedScope || scope,
|
|
1432
|
-
prBranch: cleanText(input.prBranch || existingSupervisor?.prBranch || '', 240),
|
|
1433
|
-
activeStep: existingSupervisor?.activeStep || (diagnosisValidation.valid ? 'compile_check' : 'diagnosis_gate'),
|
|
1434
|
-
activeBlocker: existingSupervisor?.activeBlocker || (diagnosisValidation.valid ? '' : 'SupportDiagnosisGate required before product-code repair.'),
|
|
1435
|
-
lastGoodCheckpoint: existingSupervisor?.lastGoodCheckpoint || 'v5_initialized',
|
|
1436
|
-
currentQaRow: existingSupervisor?.currentQaRow,
|
|
1437
|
-
processLease: input.processLease || existingSupervisor?.processLease,
|
|
1438
|
-
artifactLinks: cleanList(existingSupervisor?.artifactLinks, 40, 500),
|
|
1439
|
-
noEmailUnlessApproved: true,
|
|
1440
|
-
updatedAt: now
|
|
1441
|
-
},
|
|
1442
|
-
supportV5DiagnosisGate: diagnosisValidation.valid ? diagnosisValidation.normalized : existingDiagnosisGate,
|
|
1443
|
-
supportV5LaneMemory: {
|
|
1444
|
-
build: {
|
|
1445
|
-
lane: 'build',
|
|
1446
|
-
model: existingLaneMemory.build?.model || 'gpt-5.3-codex',
|
|
1447
|
-
threadKey: buildThreadKey,
|
|
1448
|
-
scopeSummary: existingLaneMemory.build?.scopeSummary || scope,
|
|
1449
|
-
activeBlocker: existingLaneMemory.build?.activeBlocker || '',
|
|
1450
|
-
activeQaRow: existingLaneMemory.build?.activeQaRow,
|
|
1451
|
-
changedFiles: cleanList(existingLaneMemory.build?.changedFiles, 80, 500),
|
|
1452
|
-
artifactPaths: cleanList(existingLaneMemory.build?.artifactPaths, 80, 500),
|
|
1453
|
-
latestPromptTokenEstimate: Number(existingLaneMemory.build?.latestPromptTokenEstimate || 0) || undefined,
|
|
1454
|
-
updatedAt: existingLaneMemory.build?.updatedAt || now
|
|
1455
|
-
},
|
|
1456
|
-
qa: {
|
|
1457
|
-
lane: 'qa',
|
|
1458
|
-
model: existingLaneMemory.qa?.model || 'gpt-5.4-mini',
|
|
1459
|
-
threadKey: qaThreadKey,
|
|
1460
|
-
scopeSummary: existingLaneMemory.qa?.scopeSummary || scope,
|
|
1461
|
-
activeBlocker: existingLaneMemory.qa?.activeBlocker || '',
|
|
1462
|
-
activeQaRow: existingLaneMemory.qa?.activeQaRow,
|
|
1463
|
-
changedFiles: cleanList(existingLaneMemory.qa?.changedFiles, 80, 500),
|
|
1464
|
-
artifactPaths: cleanList(existingLaneMemory.qa?.artifactPaths, 80, 500),
|
|
1465
|
-
latestPromptTokenEstimate: Number(existingLaneMemory.qa?.latestPromptTokenEstimate || 0) || undefined,
|
|
1466
|
-
updatedAt: existingLaneMemory.qa?.updatedAt || now
|
|
1467
|
-
}
|
|
1468
|
-
},
|
|
1469
|
-
supportV5StepHistory: Array.isArray(existing.supportV5StepHistory)
|
|
1470
|
-
? existing.supportV5StepHistory.slice(-80)
|
|
1471
|
-
: [],
|
|
1472
|
-
supportV5Budget: budget,
|
|
1473
|
-
supportV5RunnerIncidents: Array.isArray(existing.supportV5RunnerIncidents)
|
|
1474
|
-
? existing.supportV5RunnerIncidents.slice(-80)
|
|
1475
|
-
: [],
|
|
1476
|
-
supportV5MicrotaskLedger: ledger,
|
|
1477
|
-
supportV5ActiveMicrotaskId: diagnosisValidation.valid
|
|
1478
|
-
? activeMicrotask?.microtaskId
|
|
1479
|
-
: ledger.find((task) => task.type === 'diagnosis_gate' && !['pass', 'parked'].includes(task.status))?.microtaskId || activeMicrotask?.microtaskId,
|
|
1480
|
-
supportV5ScopeDigest: scopeDigest,
|
|
1481
|
-
supportV5MicrotaskUsageHistory: Array.isArray((existing as any).supportV5MicrotaskUsageHistory)
|
|
1482
|
-
? (existing as any).supportV5MicrotaskUsageHistory.slice(-200)
|
|
1483
|
-
: [],
|
|
1484
|
-
supportV5FailureFingerprints: Array.isArray((existing as any).supportV5FailureFingerprints)
|
|
1485
|
-
? (existing as any).supportV5FailureFingerprints.slice(-200)
|
|
1486
|
-
: [],
|
|
1487
|
-
supportV5RecoveryPlan: (existing as any).supportV5RecoveryPlan,
|
|
1488
|
-
supportV5RecoveryCheckpoint: (existing as any).supportV5RecoveryCheckpoint,
|
|
1489
|
-
supportV5RecoveryEvidenceProbe: (existing as any).supportV5RecoveryEvidenceProbe,
|
|
1490
|
-
supportV5RecoveryAction: (existing as any).supportV5RecoveryAction,
|
|
1491
|
-
supportV5RecoveryDispatchHistory: Array.isArray((existing as any).supportV5RecoveryDispatchHistory)
|
|
1492
|
-
? (existing as any).supportV5RecoveryDispatchHistory.slice(-50)
|
|
1493
|
-
: [],
|
|
1494
|
-
supportV5RecoveryDirective: (existing as any).supportV5RecoveryDirective
|
|
1495
|
-
};
|
|
1496
|
-
return diagnosisValidation.valid && diagnosisValidation.normalized
|
|
1497
|
-
? applyResolveIOSupportDiagnosisGateToMicrotasks(initialized, diagnosisValidation.normalized)
|
|
1498
|
-
: initialized;
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
|
-
export function recordResolveIOSupportV5Step(
|
|
1502
|
-
bundle: ResolveIOSupportV5StateBundle,
|
|
1503
|
-
step: ResolveIOSupportV5StepInput
|
|
1504
|
-
): ResolveIOSupportV5StateBundle {
|
|
1505
|
-
const now = isoNow(step.now);
|
|
1506
|
-
const promptTokens = Math.max(0, Number(step.promptTokenEstimate || 0) || 0);
|
|
1507
|
-
const runtimeMs = Math.max(0, Number(step.runtimeMs || 0) || 0);
|
|
1508
|
-
const microtaskId = cleanText(step.microtaskId || bundle.supportV5ActiveMicrotaskId, 160);
|
|
1509
|
-
const normalizedDiagnosisGate = step.diagnosisGate
|
|
1510
|
-
? normalizeResolveIOSupportDiagnosisGate(step.diagnosisGate, now)
|
|
1511
|
-
: undefined;
|
|
1512
|
-
const blockerFingerprint = step.blocker || step.summary
|
|
1513
|
-
? fingerprintResolveIOSupportV5Blocker(step.blocker || step.summary || '')
|
|
1514
|
-
: undefined;
|
|
1515
|
-
const evidenceHash = cleanText(step.evidenceHash, 80)
|
|
1516
|
-
|| (step.artifactPaths?.length || step.blocker || step.summary
|
|
1517
|
-
? hashResolveIOSupportV5Evidence(step.artifactPaths?.length ? step.artifactPaths : `${step.blocker || ''}\n${step.summary || ''}`)
|
|
1518
|
-
: hashResolveIOAIManagerEvidence({
|
|
1519
|
-
failureClass: step.failureClass,
|
|
1520
|
-
blocker: step.blocker,
|
|
1521
|
-
summary: step.summary,
|
|
1522
|
-
changedFiles: step.changedFiles,
|
|
1523
|
-
artifactPaths: step.artifactPaths
|
|
1524
|
-
}));
|
|
1525
|
-
const record: ResolveIOSupportV5StepRecord = {
|
|
1526
|
-
...(microtaskId ? { microtaskId } : {}),
|
|
1527
|
-
stepType: step.stepType,
|
|
1528
|
-
outcome: step.outcome,
|
|
1529
|
-
lane: step.lane,
|
|
1530
|
-
model: cleanText(step.model, 80),
|
|
1531
|
-
threadKey: cleanText(step.threadKey, 240),
|
|
1532
|
-
promptTokenEstimate: promptTokens || undefined,
|
|
1533
|
-
runtimeMs: runtimeMs || undefined,
|
|
1534
|
-
summary: cleanText(step.summary || step.blocker || step.outcome, 1200),
|
|
1535
|
-
blocker: cleanText(step.blocker, 1200),
|
|
1536
|
-
changedFiles: cleanList(step.changedFiles, 80, 500),
|
|
1537
|
-
artifactPaths: cleanList(step.artifactPaths, 80, 500),
|
|
1538
|
-
diagnosisGate: normalizedDiagnosisGate,
|
|
1539
|
-
failureClass: cleanText(step.failureClass, 80) || undefined,
|
|
1540
|
-
blockerFingerprint,
|
|
1541
|
-
evidenceHash,
|
|
1542
|
-
recordedAt: now
|
|
1543
|
-
};
|
|
1544
|
-
const diagnosisGate = normalizedDiagnosisGate || bundle.supportV5DiagnosisGate;
|
|
1545
|
-
const laneMemory = { ...bundle.supportV5LaneMemory };
|
|
1546
|
-
if (step.lane === 'build' || step.lane === 'qa') {
|
|
1547
|
-
const previous = laneMemory[step.lane];
|
|
1548
|
-
laneMemory[step.lane] = {
|
|
1549
|
-
...previous,
|
|
1550
|
-
activeBlocker: record.blocker || previous.activeBlocker || '',
|
|
1551
|
-
activeQaRow: step.activeQaRow || previous.activeQaRow,
|
|
1552
|
-
changedFiles: record.changedFiles?.length ? record.changedFiles : previous.changedFiles,
|
|
1553
|
-
artifactPaths: record.artifactPaths?.length ? record.artifactPaths : previous.artifactPaths,
|
|
1554
|
-
latestPromptTokenEstimate: promptTokens || previous.latestPromptTokenEstimate,
|
|
1555
|
-
updatedAt: now
|
|
1556
|
-
};
|
|
1557
|
-
}
|
|
1558
|
-
const supervisor = {
|
|
1559
|
-
...bundle.supportV5SupervisorState,
|
|
1560
|
-
status: step.outcome === 'ready_for_merge' ? 'complete' as const : (step.outcome === 'park_manual' || step.outcome === 'budget_stop' ? 'parked' as const : 'active' as const),
|
|
1561
|
-
activeStep: step.stepType,
|
|
1562
|
-
activeBlocker: record.blocker || '',
|
|
1563
|
-
currentQaRow: step.activeQaRow || bundle.supportV5SupervisorState.currentQaRow,
|
|
1564
|
-
lastGoodCheckpoint: step.outcome === 'pass' || step.outcome === 'ready_for_merge'
|
|
1565
|
-
? step.stepType
|
|
1566
|
-
: bundle.supportV5SupervisorState.lastGoodCheckpoint,
|
|
1567
|
-
artifactLinks: Array.from(new Set([
|
|
1568
|
-
...bundle.supportV5SupervisorState.artifactLinks,
|
|
1569
|
-
...(record.artifactPaths || [])
|
|
1570
|
-
])).slice(-80),
|
|
1571
|
-
updatedAt: now
|
|
1572
|
-
};
|
|
1573
|
-
const ledger = (bundle.supportV5MicrotaskLedger || []).map((task) => {
|
|
1574
|
-
if (task.microtaskId !== bundle.supportV5ActiveMicrotaskId) {
|
|
1575
|
-
return task;
|
|
1576
|
-
}
|
|
1577
|
-
const status: ResolveIOSupportV5MicrotaskStatus = step.outcome === 'pass' || step.outcome === 'ready_for_merge'
|
|
1578
|
-
? 'pass'
|
|
1579
|
-
: step.outcome === 'park_manual' || step.outcome === 'budget_stop'
|
|
1580
|
-
? 'parked'
|
|
1581
|
-
: step.outcome === 'needs_repair' || step.outcome === 'retry_same_step'
|
|
1582
|
-
? 'needs_repair'
|
|
1583
|
-
: 'in_progress';
|
|
1584
|
-
return {
|
|
1585
|
-
...task,
|
|
1586
|
-
status,
|
|
1587
|
-
blocker: record.blocker || task.blocker,
|
|
1588
|
-
promptTokenEstimate: promptTokens || task.promptTokenEstimate,
|
|
1589
|
-
attempts: task.attempts + (step.outcome === 'pass' || step.outcome === 'ready_for_merge' ? 0 : 1),
|
|
1590
|
-
updatedAt: now
|
|
1591
|
-
};
|
|
1592
|
-
});
|
|
1593
|
-
const failureFingerprint = record.failureClass && record.blockerFingerprint && record.evidenceHash
|
|
1594
|
-
? {
|
|
1595
|
-
stepType: record.stepType,
|
|
1596
|
-
failureClass: cleanText(record.failureClass, 80),
|
|
1597
|
-
blockerFingerprint: record.blockerFingerprint,
|
|
1598
|
-
evidenceHash: record.evidenceHash,
|
|
1599
|
-
recordedAt: now
|
|
1600
|
-
}
|
|
1601
|
-
: undefined;
|
|
1602
|
-
const managerDecision = decideResolveIOAIManagerPolicy({
|
|
1603
|
-
history: [...bundle.supportV5StepHistory, record],
|
|
1604
|
-
current: record,
|
|
1605
|
-
maxSameFailureRepeats: buildResolveIOSupportV5Budget(bundle.supportV5Budget).maxRepeatedNoProgress,
|
|
1606
|
-
maxPingPongTransitions: 3,
|
|
1607
|
-
infraFailureClasses: ['infra', 'compile']
|
|
1608
|
-
});
|
|
1609
|
-
const previousRecord = bundle.supportV5StepHistory[bundle.supportV5StepHistory.length - 1];
|
|
1610
|
-
const nextLoopCount = managerDecision.loopBudgetShouldReset
|
|
1611
|
-
|| previousRecord?.failureClass !== record.failureClass
|
|
1612
|
-
|| previousRecord?.blockerFingerprint !== record.blockerFingerprint
|
|
1613
|
-
|| previousRecord?.evidenceHash !== record.evidenceHash
|
|
1614
|
-
? 1
|
|
1615
|
-
: bundle.supportV5Budget.loopCount + 1;
|
|
1616
|
-
const nextMicrotask = selectResolveIOSupportV5ActiveMicrotask(ledger, bundle.supportV5ActiveMicrotaskId);
|
|
1617
|
-
const nextBundle: ResolveIOSupportV5StateBundle = {
|
|
1618
|
-
...bundle,
|
|
1619
|
-
supportV5SupervisorState: supervisor,
|
|
1620
|
-
supportV5DiagnosisGate: diagnosisGate,
|
|
1621
|
-
supportV5LaneMemory: laneMemory,
|
|
1622
|
-
supportV5StepHistory: [...bundle.supportV5StepHistory, record].slice(-100),
|
|
1623
|
-
supportV5Budget: {
|
|
1624
|
-
...bundle.supportV5Budget,
|
|
1625
|
-
totalPromptTokenEstimate: bundle.supportV5Budget.totalPromptTokenEstimate + promptTokens,
|
|
1626
|
-
totalRuntimeMs: bundle.supportV5Budget.totalRuntimeMs + runtimeMs,
|
|
1627
|
-
loopCount: nextLoopCount
|
|
1628
|
-
},
|
|
1629
|
-
supportV5MicrotaskLedger: ledger,
|
|
1630
|
-
supportV5ActiveMicrotaskId: nextMicrotask?.microtaskId,
|
|
1631
|
-
supportV5MicrotaskUsageHistory: bundle.supportV5MicrotaskUsageHistory || [],
|
|
1632
|
-
supportV5FailureFingerprints: failureFingerprint
|
|
1633
|
-
? [...(bundle.supportV5FailureFingerprints || []), failureFingerprint].slice(-200)
|
|
1634
|
-
: (bundle.supportV5FailureFingerprints || []),
|
|
1635
|
-
supportV5RecoveryPlan: managerDecision.recoveryPlan,
|
|
1636
|
-
supportV5RecoveryCheckpoint: managerDecision.recoveryCheckpoint,
|
|
1637
|
-
supportV5RecoveryEvidenceProbe: managerDecision.recoveryEvidenceProbe,
|
|
1638
|
-
supportV5RecoveryAction: managerDecision.recoveryAction
|
|
1639
|
-
};
|
|
1640
|
-
if (normalizedDiagnosisGate && validateResolveIOSupportDiagnosisGate(normalizedDiagnosisGate).valid) {
|
|
1641
|
-
return applyResolveIOSupportDiagnosisGateToMicrotasks(nextBundle, normalizedDiagnosisGate);
|
|
1642
|
-
}
|
|
1643
|
-
return nextBundle;
|
|
1644
|
-
}
|
|
1645
|
-
|
|
1646
|
-
export function recordResolveIOSupportV5MicrotaskUsage(
|
|
1647
|
-
bundle: ResolveIOSupportV5StateBundle,
|
|
1648
|
-
usage: Omit<ResolveIOSupportV5MicrotaskUsage, 'recordedAt'>
|
|
1649
|
-
): ResolveIOSupportV5StateBundle {
|
|
1650
|
-
const record: ResolveIOSupportV5MicrotaskUsage = {
|
|
1651
|
-
...usage,
|
|
1652
|
-
microtaskId: cleanText(usage.microtaskId, 160),
|
|
1653
|
-
threadKey: cleanText(usage.threadKey, 240),
|
|
1654
|
-
model: cleanText(usage.model, 80),
|
|
1655
|
-
promptTokenEstimate: Math.max(0, Number(usage.promptTokenEstimate || 0) || 0),
|
|
1656
|
-
promptSections: Array.isArray(usage.promptSections)
|
|
1657
|
-
? usage.promptSections.map((section) => ({
|
|
1658
|
-
name: cleanText(section.name, 120),
|
|
1659
|
-
tokenEstimate: Math.max(0, Number(section.tokenEstimate || 0) || 0)
|
|
1660
|
-
})).filter((section) => section.name)
|
|
1661
|
-
: [],
|
|
1662
|
-
recordedAt: isoNow()
|
|
1663
|
-
};
|
|
1664
|
-
const ledger = (bundle.supportV5MicrotaskLedger || []).map((task) => task.microtaskId === record.microtaskId
|
|
1665
|
-
? {
|
|
1666
|
-
...task,
|
|
1667
|
-
promptTokenEstimate: record.promptTokenEstimate,
|
|
1668
|
-
updatedAt: record.recordedAt
|
|
1669
|
-
}
|
|
1670
|
-
: task);
|
|
1671
|
-
return {
|
|
1672
|
-
...bundle,
|
|
1673
|
-
supportV5MicrotaskLedger: ledger,
|
|
1674
|
-
supportV5MicrotaskUsageHistory: [
|
|
1675
|
-
...(bundle.supportV5MicrotaskUsageHistory || []),
|
|
1676
|
-
record
|
|
1677
|
-
].slice(-200)
|
|
1678
|
-
};
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
export function decideResolveIOSupportV5Continuation(bundle: ResolveIOSupportV5StateBundle): ResolveIOSupportV5ContinuationDecision {
|
|
1682
|
-
const history = bundle.supportV5StepHistory || [];
|
|
1683
|
-
const budget = buildResolveIOSupportV5Budget(bundle.supportV5Budget);
|
|
1684
|
-
const last = history[history.length - 1];
|
|
1685
|
-
const activeMicrotaskId = cleanText(bundle.supportV5ActiveMicrotaskId, 160);
|
|
1686
|
-
const blockerFingerprint = fingerprintResolveIOSupportV5Blocker(last?.blocker || last?.summary || '');
|
|
1687
|
-
let repeatedNoProgressCount = 0;
|
|
1688
|
-
for (let index = history.length - 1; index >= 0; index -= 1) {
|
|
1689
|
-
const item = history[index];
|
|
1690
|
-
if (activeMicrotaskId && cleanText((item as any).microtaskId, 160) !== activeMicrotaskId) {
|
|
1691
|
-
continue;
|
|
1692
|
-
}
|
|
1693
|
-
if (item.outcome === 'pass' || item.outcome === 'ready_for_merge') {
|
|
1694
|
-
break;
|
|
1695
|
-
}
|
|
1696
|
-
if (item.stepType !== last?.stepType) {
|
|
1697
|
-
break;
|
|
1698
|
-
}
|
|
1699
|
-
if (fingerprintResolveIOSupportV5Blocker(item.blocker || item.summary || '') === blockerFingerprint) {
|
|
1700
|
-
repeatedNoProgressCount += 1;
|
|
1701
|
-
}
|
|
1702
|
-
}
|
|
1703
|
-
const budgetExceeded = budget.loopCount >= budget.maxLoopsPerTicket
|
|
1704
|
-
|| (last?.promptTokenEstimate || 0) > budget.maxPromptTokensPerNonInitialStep;
|
|
1705
|
-
const repeatedFailure = last ? decideResolveIOSupportV5RepeatedFailureStop({
|
|
1706
|
-
history,
|
|
1707
|
-
failureClass: last.failureClass,
|
|
1708
|
-
blocker: last.blocker || last.summary,
|
|
1709
|
-
evidenceHash: last.evidenceHash,
|
|
1710
|
-
limit: budget.maxRepeatedNoProgress,
|
|
1711
|
-
ignoreInfra: true
|
|
1712
|
-
}) : null;
|
|
1713
|
-
const recoveryPlanFor = (
|
|
1714
|
-
action: string,
|
|
1715
|
-
reason: string,
|
|
1716
|
-
extra: Partial<ResolveIOAIManagerRecoveryPlanInput> = {}
|
|
1717
|
-
): ResolveIOAIManagerRecoveryPlan => buildResolveIOAIManagerRecoveryPlan({
|
|
1718
|
-
action,
|
|
1719
|
-
reason,
|
|
1720
|
-
failureClass: last?.failureClass,
|
|
1721
|
-
lane: last?.lane || 'supervisor',
|
|
1722
|
-
stepType: last?.stepType || bundle.supportV5SupervisorState.activeStep,
|
|
1723
|
-
blocker: last?.blocker || last?.summary,
|
|
1724
|
-
changedFiles: last?.changedFiles,
|
|
1725
|
-
artifactPaths: last?.artifactPaths,
|
|
1726
|
-
maxSameFailureRepeats: budget.maxRepeatedNoProgress,
|
|
1727
|
-
...extra
|
|
1728
|
-
});
|
|
1729
|
-
const recoveryCheckpointFor = (
|
|
1730
|
-
recoveryPlan: ResolveIOAIManagerRecoveryPlan
|
|
1731
|
-
): ResolveIOAIManagerRecoveryCheckpoint => buildResolveIOAIManagerRecoveryCheckpoint({
|
|
1732
|
-
plan: recoveryPlan,
|
|
1733
|
-
current: last
|
|
1734
|
-
});
|
|
1735
|
-
const recoveryFieldsFor = (
|
|
1736
|
-
recoveryPlan: ResolveIOAIManagerRecoveryPlan
|
|
1737
|
-
): Pick<ResolveIOSupportV5ContinuationDecision, 'recoveryPlan' | 'recoveryCheckpoint' | 'recoveryEvidenceProbe' | 'recoveryAction'> => {
|
|
1738
|
-
const recoveryCheckpoint = recoveryCheckpointFor(recoveryPlan);
|
|
1739
|
-
const recoveryEvidenceProbe = buildResolveIOAIManagerRecoveryEvidenceProbe({
|
|
1740
|
-
checkpoint: recoveryCheckpoint,
|
|
1741
|
-
current: last
|
|
1742
|
-
});
|
|
1743
|
-
return {
|
|
1744
|
-
recoveryPlan,
|
|
1745
|
-
recoveryCheckpoint,
|
|
1746
|
-
recoveryEvidenceProbe,
|
|
1747
|
-
recoveryAction: buildResolveIOAIManagerRecoveryActionPacket({
|
|
1748
|
-
plan: recoveryPlan,
|
|
1749
|
-
checkpoint: recoveryCheckpoint,
|
|
1750
|
-
probe: recoveryEvidenceProbe,
|
|
1751
|
-
current: last
|
|
1752
|
-
})
|
|
1753
|
-
};
|
|
1754
|
-
};
|
|
1755
|
-
if (budgetExceeded) {
|
|
1756
|
-
const recoveryPlan = recoveryPlanFor('manual_handoff', 'support_v5_budget_guard', {
|
|
1757
|
-
productRepairFailure: false
|
|
1758
|
-
});
|
|
1759
|
-
return {
|
|
1760
|
-
action: 'park',
|
|
1761
|
-
reason: 'support_v5_budget_guard',
|
|
1762
|
-
nextStep: last?.stepType || 'cleanup',
|
|
1763
|
-
repeatedNoProgressCount,
|
|
1764
|
-
budgetExceeded,
|
|
1765
|
-
...recoveryFieldsFor(recoveryPlan)
|
|
1766
|
-
};
|
|
1767
|
-
}
|
|
1768
|
-
if (repeatedNoProgressCount > budget.maxRepeatedNoProgress) {
|
|
1769
|
-
const recoveryPlan = recoveryPlanFor('park_repeated_failure', 'support_v5_repeated_no_progress', {
|
|
1770
|
-
productRepairFailure: true
|
|
1771
|
-
});
|
|
1772
|
-
return {
|
|
1773
|
-
action: 'park',
|
|
1774
|
-
reason: 'support_v5_repeated_no_progress',
|
|
1775
|
-
nextStep: last?.stepType || 'cleanup',
|
|
1776
|
-
repeatedNoProgressCount,
|
|
1777
|
-
budgetExceeded,
|
|
1778
|
-
...recoveryFieldsFor(recoveryPlan)
|
|
1779
|
-
};
|
|
1780
|
-
}
|
|
1781
|
-
if (repeatedFailure?.shouldStop) {
|
|
1782
|
-
const recoveryPlan = recoveryPlanFor(
|
|
1783
|
-
repeatedFailure.reason === 'support_v5_ping_pong_failure_loop' ? 'park_ping_pong' : 'park_repeated_failure',
|
|
1784
|
-
repeatedFailure.reason,
|
|
1785
|
-
{
|
|
1786
|
-
failureClass: repeatedFailure.failureClass,
|
|
1787
|
-
productRepairFailure: true
|
|
1788
|
-
}
|
|
1789
|
-
);
|
|
1790
|
-
return {
|
|
1791
|
-
action: 'park',
|
|
1792
|
-
reason: repeatedFailure.reason,
|
|
1793
|
-
nextStep: last?.stepType || 'cleanup',
|
|
1794
|
-
repeatedNoProgressCount: repeatedFailure.repeatedCount,
|
|
1795
|
-
budgetExceeded,
|
|
1796
|
-
...recoveryFieldsFor(recoveryPlan)
|
|
1797
|
-
};
|
|
1798
|
-
}
|
|
1799
|
-
const recoveryPlan = recoveryPlanFor('continue', 'support_v5_continue');
|
|
1800
|
-
return {
|
|
1801
|
-
action: 'continue',
|
|
1802
|
-
reason: 'support_v5_continue',
|
|
1803
|
-
nextStep: last?.stepType || bundle.supportV5SupervisorState.activeStep,
|
|
1804
|
-
repeatedNoProgressCount,
|
|
1805
|
-
budgetExceeded: false,
|
|
1806
|
-
...recoveryFieldsFor(recoveryPlan)
|
|
1807
|
-
};
|
|
1808
|
-
}
|
|
1809
|
-
|
|
1810
|
-
export function buildResolveIOSupportV5DiagnoseFirstPrompt(lines: {
|
|
1811
|
-
goal?: string;
|
|
1812
|
-
approvedScope?: string[];
|
|
1813
|
-
activeStep?: ResolveIOSupportV5StepType;
|
|
1814
|
-
activeBlocker?: string;
|
|
1815
|
-
lane?: ResolveIOSupportV5Lane;
|
|
1816
|
-
laneSummary?: string;
|
|
1817
|
-
currentQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];
|
|
1818
|
-
artifactPaths?: string[];
|
|
1819
|
-
changedFiles?: string[];
|
|
1820
|
-
}): string[] {
|
|
1821
|
-
return [
|
|
1822
|
-
'Support Runner V5 contract: act like a guarded autonomous engineer, not a gate checklist.',
|
|
1823
|
-
'Start with Diagnose First: observed evidence, likely cause, smallest next action, and expected proof.',
|
|
1824
|
-
'Use compact lane memory and current artifacts before asking for broad ticket context.',
|
|
1825
|
-
'Do not send customer email. Do not write production data. Do not spawn duplicate build, QA, server, client, Mongo, browser, or Codex processes.',
|
|
1826
|
-
'If repairing, inspect logs/artifacts/source/diff first; make the smallest code or localhost-data change, then run the smallest finite self-gate.',
|
|
1827
|
-
'For build repairs, prefer `npm run build-prod -- --watch=false`, a targeted `tsc --noEmit`, or a focused unit test. `npm run build-dev` is forbidden for support microtasks because it is slow/watch-oriented and can leave heavy esbuild work. If no finite gate exists, return a blocked self-gate with the exact reason instead of running build-dev.',
|
|
1828
|
-
'If QA fails, retest the failed row before advancing; if the same blocker repeats without new proof, park with the exact blocker.',
|
|
1829
|
-
lines.goal ? `Goal: ${cleanText(lines.goal, 500)}` : '',
|
|
1830
|
-
cleanList(lines.approvedScope, 12, 240).length ? `Approved scope: ${cleanList(lines.approvedScope, 12, 240).join(' | ')}` : '',
|
|
1831
|
-
lines.activeStep ? `Active step: ${lines.activeStep}` : '',
|
|
1832
|
-
lines.lane ? `Lane: ${lines.lane}` : '',
|
|
1833
|
-
lines.laneSummary ? `Lane memory: ${cleanText(lines.laneSummary, 700)}` : '',
|
|
1834
|
-
lines.activeBlocker ? `Active blocker: ${cleanText(lines.activeBlocker, 800)}` : '',
|
|
1835
|
-
lines.currentQaRow?.workflow ? `Current QA row: ${cleanText(lines.currentQaRow.workflow, 300)}` : '',
|
|
1836
|
-
lines.currentQaRow?.route ? `Current QA route: ${cleanText(lines.currentQaRow.route, 300)}` : '',
|
|
1837
|
-
cleanList(lines.changedFiles, 12, 200).length ? `Changed files: ${cleanList(lines.changedFiles, 12, 200).join(', ')}` : '',
|
|
1838
|
-
cleanList(lines.artifactPaths, 12, 240).length ? `Artifacts: ${cleanList(lines.artifactPaths, 12, 240).join(', ')}` : ''
|
|
1839
|
-
].filter(Boolean);
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
export function buildResolveIOSupportV5MicrotaskPrompt(input: {
|
|
1843
|
-
bundle: ResolveIOSupportV5StateBundle;
|
|
1844
|
-
lane: 'build' | 'qa';
|
|
1845
|
-
model?: string;
|
|
1846
|
-
stage?: string;
|
|
1847
|
-
failureText?: string;
|
|
1848
|
-
changedFiles?: string[];
|
|
1849
|
-
artifactPaths?: string[];
|
|
1850
|
-
targetFiles?: string[];
|
|
1851
|
-
contextSnippets?: string[];
|
|
1852
|
-
activeQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];
|
|
1853
|
-
}): {
|
|
1854
|
-
prompt: string;
|
|
1855
|
-
promptTokenEstimate: number;
|
|
1856
|
-
promptSections: ResolveIOSupportV5UsageSection[];
|
|
1857
|
-
activeMicrotask?: ResolveIOSupportV5Microtask;
|
|
1858
|
-
withinCap: boolean;
|
|
1859
|
-
withinHardCap: boolean;
|
|
1860
|
-
cap: number;
|
|
1861
|
-
hardCap: number;
|
|
1862
|
-
reason?: string;
|
|
1863
|
-
} {
|
|
1864
|
-
const activeMicrotask = selectResolveIOSupportV5ActiveMicrotask(
|
|
1865
|
-
input.bundle.supportV5MicrotaskLedger || [],
|
|
1866
|
-
input.bundle.supportV5ActiveMicrotaskId
|
|
1867
|
-
);
|
|
1868
|
-
const diagnosisValidation = validateResolveIOSupportDiagnosisGate(input.bundle.supportV5DiagnosisGate);
|
|
1869
|
-
const diagnosisGate = diagnosisValidation.normalized || input.bundle.supportV5DiagnosisGate;
|
|
1870
|
-
const diagnosisActive = activeMicrotask?.type === 'diagnosis_gate';
|
|
1871
|
-
const budget = buildResolveIOSupportV5PromptBudget();
|
|
1872
|
-
const repairLike = Boolean(input.failureText || activeMicrotask?.status === 'needs_repair' || /repair/i.test(String(input.stage || activeMicrotask?.type || '')));
|
|
1873
|
-
const cap = repairLike
|
|
1874
|
-
? budget.repairMicrotaskCap
|
|
1875
|
-
: input.lane === 'qa'
|
|
1876
|
-
? budget.qaMicrotaskCap
|
|
1877
|
-
: budget.buildMicrotaskCap;
|
|
1878
|
-
const hardCap = repairLike
|
|
1879
|
-
? budget.repairMicrotaskHardCap
|
|
1880
|
-
: input.lane === 'qa'
|
|
1881
|
-
? budget.qaMicrotaskHardCap
|
|
1882
|
-
: budget.buildMicrotaskHardCap;
|
|
1883
|
-
const laneMemory = input.bundle.supportV5LaneMemory[input.lane];
|
|
1884
|
-
const taskThreadKey = activeMicrotask?.threadKey || laneMemory.threadKey;
|
|
1885
|
-
const changedFiles = cleanList(input.changedFiles?.length ? input.changedFiles : laneMemory.changedFiles, 8, 160);
|
|
1886
|
-
const artifactPaths = cleanList(input.artifactPaths?.length ? input.artifactPaths : laneMemory.artifactPaths, 8, 200);
|
|
1887
|
-
const targetFiles = cleanList(input.targetFiles?.length ? input.targetFiles : activeMicrotask?.targetFiles, 5, 160);
|
|
1888
|
-
const contextSnippets = cleanList(input.contextSnippets, 5, 360);
|
|
1889
|
-
const qaRow = input.activeQaRow || activeMicrotask?.lane === 'qa'
|
|
1890
|
-
? input.activeQaRow || laneMemory.activeQaRow || input.bundle.supportV5SupervisorState.currentQaRow
|
|
1891
|
-
: undefined;
|
|
1892
|
-
const sections = [
|
|
1893
|
-
{
|
|
1894
|
-
name: 'microtask_contract',
|
|
1895
|
-
text: [
|
|
1896
|
-
'Support Runner V5 Microtask Contract.',
|
|
1897
|
-
'Use the existing persistent lane thread. Do not start a fresh thread.',
|
|
1898
|
-
'Do exactly one microtask and one proof gate. Do not replay ticket triage, prior plans, attachments, broad QA checklist, or unrelated scope.',
|
|
1899
|
-
'If context is insufficient, request the smallest missing file/log/artifact by path and park this microtask; do not broaden the prompt.',
|
|
1900
|
-
'Do not send customer email. Do not deploy. Do not spawn duplicate server/client/Mongo/browser/Codex processes.',
|
|
1901
|
-
diagnosisActive
|
|
1902
|
-
? 'Diagnosis gate hard boundary: read-only investigation only. Do not edit source, generated files, package files, tests, fixtures, QA artifacts, or local data. Return the diagnosis JSON contract only.'
|
|
1903
|
-
: input.lane === 'qa'
|
|
1904
|
-
? 'QA lane hard boundary: the platform preflight owns compile, dependency install, Mongo/server/client startup, and Angular startup. This lane owns only browser/data proof and QA artifacts unless the prompt explicitly says preflight was skipped.'
|
|
1905
|
-
: 'Build lane hard boundary: do not run `npm run build-dev`, `ng build`, `npm run server`, `npm run client`, `ng serve`, `run-local-qa.sh`, browser automation, or any watch/long-lived command. If a broad compile gate is needed, run only `npm run build-prod -- --watch=false`; otherwise use a targeted finite check or return the precise blocker.'
|
|
1906
|
-
].join('\n')
|
|
1907
|
-
},
|
|
1908
|
-
diagnosisActive ? {
|
|
1909
|
-
name: 'root_cause_first_diagnosis_contract',
|
|
1910
|
-
text: [
|
|
1911
|
-
'Before any product-code repair, produce strict JSON only:',
|
|
1912
|
-
'{"support_diagnosis_gate":{"issue_case":{"customer_complaint":"","expected_result":"","observed_result":"","route_module":"","account_customer_context":"","reproduction_status":"reproduced|blocked|classified","reproduction_blocker":""},"issue_class":"no_op_submit|missing_wrong_data|filter_query_mismatch|invoice_pdf_export|upload_import|route_auth_hydration|slow_query_performance","accepted_hypothesis":{"statement":"","falsifiable_test":"","evidence":[""]},"rejected_alternatives":[""],"failing_path":{"frontend":"","backend":"","shared_library":"","data_query":"","description":""},"owner_files":["small/exact/file.ts"],"proof_plan":{"before":"","before_state_unavailable_reason":"","action":"","after":"","business_assertion":"","route":"","data_assertion":"","artifact_expectation":""},"similar_tickets":[],"similar_commits":[],"evidence":[{"type":"ticket|browser|mongo|log|code|commit|qa|other","summary":"","artifactPath":""}],"status":"passed"}}',
|
|
1913
|
-
'Owner files must be a small exact editable set, not directories, globs, generated wrappers, or broad repo areas.',
|
|
1914
|
-
'The accepted hypothesis must be falsifiable and backed by evidence; prior similar tickets or commits are hints only and cannot bypass fresh diagnosis.',
|
|
1915
|
-
'The proof plan must be before/action/after business proof. If before-state proof is impossible, explain exactly why in before_state_unavailable_reason.'
|
|
1916
|
-
].join('\n')
|
|
1917
|
-
} : {
|
|
1918
|
-
name: 'diagnosis_gate_context',
|
|
1919
|
-
text: diagnosisValidation.valid && diagnosisGate ? [
|
|
1920
|
-
`Diagnosis issue class: ${(diagnosisGate as ResolveIOSupportDiagnosisGate).issue_class}`,
|
|
1921
|
-
`Accepted hypothesis: ${(diagnosisGate as ResolveIOSupportDiagnosisGate).accepted_hypothesis.statement}`,
|
|
1922
|
-
`Failing path: ${(diagnosisGate as ResolveIOSupportDiagnosisGate).failing_path.description || (diagnosisGate as ResolveIOSupportDiagnosisGate).failing_path.frontend || (diagnosisGate as ResolveIOSupportDiagnosisGate).failing_path.backend || ''}`,
|
|
1923
|
-
`Owner files: ${(diagnosisGate as ResolveIOSupportDiagnosisGate).owner_files.join(', ')}`,
|
|
1924
|
-
`Business proof required: ${(diagnosisGate as ResolveIOSupportDiagnosisGate).proof_plan.business_assertion}`,
|
|
1925
|
-
`Before/action/after: ${(diagnosisGate as ResolveIOSupportDiagnosisGate).proof_plan.before || (diagnosisGate as ResolveIOSupportDiagnosisGate).proof_plan.before_state_unavailable_reason} -> ${(diagnosisGate as ResolveIOSupportDiagnosisGate).proof_plan.action} -> ${(diagnosisGate as ResolveIOSupportDiagnosisGate).proof_plan.after}`
|
|
1926
|
-
].filter(Boolean).join('\n') : 'SupportDiagnosisGate is not valid. Park instead of editing product code.'
|
|
1927
|
-
},
|
|
1928
|
-
{
|
|
1929
|
-
name: 'scope_digest',
|
|
1930
|
-
text: cleanText(input.bundle.supportV5ScopeDigest || input.bundle.supportV5SupervisorState.approvedScope, 900)
|
|
1931
|
-
},
|
|
1932
|
-
{
|
|
1933
|
-
name: 'active_microtask',
|
|
1934
|
-
text: activeMicrotask ? [
|
|
1935
|
-
`Microtask id: ${activeMicrotask.microtaskId}`,
|
|
1936
|
-
`Lane: ${input.lane}`,
|
|
1937
|
-
`Type: ${activeMicrotask.type}`,
|
|
1938
|
-
`Status: ${activeMicrotask.status}`,
|
|
1939
|
-
`Objective: ${cleanText(activeMicrotask.objective, 360)}`,
|
|
1940
|
-
`Self-gate: ${cleanText(activeMicrotask.selfGate, 260)}`,
|
|
1941
|
-
`Acceptance proof: ${cleanText(activeMicrotask.acceptanceProof, 260)}`,
|
|
1942
|
-
`Attempts on this microtask: ${activeMicrotask.attempts}`,
|
|
1943
|
-
`Thread key: ${taskThreadKey}`
|
|
1944
|
-
].join('\n') : 'No active microtask found. Park and report support_v5_microtask_missing.'
|
|
1945
|
-
},
|
|
1946
|
-
{
|
|
1947
|
-
name: 'failure_delta',
|
|
1948
|
-
text: input.failureText ? `Latest blocker/failure delta: ${cleanText(input.failureText, 700)}` : ''
|
|
1949
|
-
},
|
|
1950
|
-
{
|
|
1951
|
-
name: 'target_context',
|
|
1952
|
-
text: [
|
|
1953
|
-
targetFiles.length ? `Target files: ${targetFiles.join(', ')}` : '',
|
|
1954
|
-
changedFiles.length ? `Changed files: ${changedFiles.join(', ')}` : '',
|
|
1955
|
-
artifactPaths.length ? `Artifacts: ${artifactPaths.join(', ')}` : '',
|
|
1956
|
-
qaRow?.workflow ? `QA row workflow: ${cleanText(qaRow.workflow, 220)}` : '',
|
|
1957
|
-
qaRow?.route ? `QA row route: ${cleanText(qaRow.route, 220)}` : '',
|
|
1958
|
-
qaRow?.assertion ? `QA row assertion: ${cleanText(qaRow.assertion, 260)}` : '',
|
|
1959
|
-
contextSnippets.length ? `Relevant snippets:\n${contextSnippets.join('\n---\n')}` : ''
|
|
1960
|
-
].filter(Boolean).join('\n')
|
|
1961
|
-
},
|
|
1962
|
-
input.lane === 'qa' ? {
|
|
1963
|
-
name: 'qa_browser_evidence_contract',
|
|
1964
|
-
text: [
|
|
1965
|
-
'QA lane first action after preflight: collect fresh browser evidence for the active row, not a proof review of existing route/auth artifacts.',
|
|
1966
|
-
'Use the already-running localhost harness and staged env. Before any shell command, run `source .resolveio-support-tools/env.sh 2>/dev/null || source ../.resolveio-support-tools/env.sh 2>/dev/null || true`; then use `$RESOLVEIO_SUPPORT_QA_CLIENT_URL`, `$RESOLVEIO_SUPPORT_QA_SERVER_URL`, `$PUPPETEER_EXECUTABLE_PATH`, and `$CHROME_BIN`.',
|
|
1967
|
-
'Required auth replay helper inside every Puppeteer row script: `const storage=JSON.parse(fs.readFileSync("qa-artifacts/auth-bootstrap-storage-state.json","utf8")); const entries=[...(Array.isArray(storage.localStorageEntries)?storage.localStorageEntries:[]), ...(Array.isArray(storage.localStorage)?storage.localStorage:Object.entries(storage.localStorage||{}).map(([key,value])=>({key,value}))), ...((storage.origins||[]).flatMap(o=>o.localStorage||[]))].map(e=>({key:e.key||e.name,value:e.value})).filter(e=>e.key); const clientUrl=process.env.RESOLVEIO_SUPPORT_QA_CLIENT_URL||process.env.RESOLVEIO_RUNNER_QA_CLIENT_URL; const rowRoute="<ACTIVE_QA_ROUTE>"; await page.goto(clientUrl,{waitUntil:"domcontentloaded"}); await page.evaluate(items=>{localStorage.clear(); for(const item of items)localStorage.setItem(item.key,item.value);}, entries); await page.goto(new URL(rowRoute, clientUrl).href,{waitUntil:"domcontentloaded"});` Replace `<ACTIVE_QA_ROUTE>` with the active row route before running. A screenshot of `/home`, the login screen, or a shell route after this helper means the QA script navigated to the wrong route or storage is stale; rerun the same row with the active route before returning an app blocker.',
|
|
1968
|
-
'Allowed first command shape: one bounded `node`/Puppeteer row script that reads `qa-artifacts/auth-bootstrap-storage-state.json`, opens `$RESOLVEIO_SUPPORT_QA_CLIENT_URL`, seeds localStorage, navigates to the active QA route with `new URL(activeRoute, clientUrl).href`, drives the visible workflow, captures screenshot/caption, and updates the active matrix row. A `/home` proof is invalid for a locked non-home route.',
|
|
1969
|
-
'Forbidden in QA lane after preflight: `npm run build`, `npm run build-dev`, `npm run build-prod`, `ng build`, `npm install`, `npm ci`, `npm run server`, `npm run client`, `ng serve`, `gulp`, `mongod`, `run-local-qa.sh`, and broad source discovery. If a build/startup/dependency problem is suspected, return `blocked` or `needs-fix` with the existing qa-artifacts log paths instead of launching those commands.',
|
|
1970
|
-
'Launch Puppeteer from `PUPPETEER_EXECUTABLE_PATH || CHROME_BIN`, seed localStorage from `qa-artifacts/auth-bootstrap-storage-state.json`, then navigate to the active QA route.',
|
|
1971
|
-
'Before passing, confirm `qa-artifacts/auth-bootstrap-result.json` used the ticket reporter or named affected user when available. If it used generic admin/dev while `qa-live-data-seed-result.json.selected.qa_user_context` names a reporter/affected user, rerun auth as that user or return needs-fix.',
|
|
1972
|
-
'Drive the visible customer workflow for this one row. Capture a new customer-facing screenshot/caption and update `qa-artifacts/qa-coverage-matrix.json` with workflow, route, data id/name, assertion, screenshot path, caption, and pass/failed/blocked status.',
|
|
1973
|
-
'After selecting any From/To, source/target, dropdown, combobox, rio-select, filter, item, customer, yard, chemical, or treatment-plan value, read the visible control text back from the DOM. If it still contains placeholder text such as Select Chemical, Select Yard, Select Customer, Select Treatment Plan Type, Loading..., empty, null, or undefined, do not click the action button and do not mark pass. Capture the selected-state blocker screenshot/DOM text and return needs-fix.',
|
|
1974
|
-
'If the row needs persisted data proof, create that proof yourself in the same bounded QA command by querying localhost QA Mongo through process.env.MONGO_URL after the visible UI action. Write the result under qa-artifacts/ as JSON and reference that path in the matrix. Do not ask for a missing post-action DB artifact while the local QA stack is running; either write it or return needs-fix with the exact query/script error. For update-interchangeables rows, the JSON must include concrete non-placeholder fromText and toText, before/after counts or sample documents for treatment plans and tank/interchangeable records, and must fail if either selected value is only an arrow/placeholder or if the persisted collections are empty.',
|
|
1975
|
-
'If the row names multiple concrete entities such as assets, units, BOLs, invoices, chemicals, customers, yards, or numbered records, prove every named entity. Do not pass by proving only one representative record.',
|
|
1976
|
-
'For customer-reported data bugs, use production-seeded localhost records from `qa-live-data-seed-result.json`. If the exact named record is missing from the seed, fail the row as a seed/query blocker instead of testing a substitute record.',
|
|
1977
|
-
'Route-ready, auth-bootstrap, shell, header-only, and empty-list screenshots do not satisfy this microtask. If the row cannot be proven, capture the blocker screenshot/DOM state and return needs-fix with that exact blocker.',
|
|
1978
|
-
'Do not run compile/startup/npm install, do not spawn another server/client/Mongo, and do not inspect broad source trees before the first browser evidence command.'
|
|
1979
|
-
].join('\n')
|
|
1980
|
-
} : {
|
|
1981
|
-
name: 'non_qa_noop',
|
|
1982
|
-
text: ''
|
|
1983
|
-
},
|
|
1984
|
-
{
|
|
1985
|
-
name: 'return_contract',
|
|
1986
|
-
text: diagnosisActive
|
|
1987
|
-
? 'Return strict JSON only with support_diagnosis_gate. Do not include Markdown and do not edit files.'
|
|
1988
|
-
: input.lane === 'qa'
|
|
1989
|
-
? 'Return strict JSON only: {"status":"pass"|"needs-fix"|"blocked","microtaskId":"","summary":"","evidence":[""],"artifacts":[""],"next_actions":[""]}.'
|
|
1990
|
-
: 'Return concise Markdown with: Microtask Result, Root Cause, Changes, Self-Gate, Acceptance Proof, Residual Risk.'
|
|
1991
|
-
}
|
|
1992
|
-
].filter((section) => cleanText(section.text, 20));
|
|
1993
|
-
const promptSections = sections.map((section) => ({
|
|
1994
|
-
name: section.name,
|
|
1995
|
-
tokenEstimate: estimateTextTokens(section.text)
|
|
1996
|
-
}));
|
|
1997
|
-
const prompt = sections.map((section) => section.text).join('\n\n');
|
|
1998
|
-
const promptTokenEstimate = estimateTextTokens(prompt);
|
|
1999
|
-
return {
|
|
2000
|
-
prompt,
|
|
2001
|
-
promptTokenEstimate,
|
|
2002
|
-
promptSections,
|
|
2003
|
-
activeMicrotask,
|
|
2004
|
-
withinCap: promptTokenEstimate <= cap,
|
|
2005
|
-
withinHardCap: promptTokenEstimate <= hardCap,
|
|
2006
|
-
cap,
|
|
2007
|
-
hardCap,
|
|
2008
|
-
reason: promptTokenEstimate > hardCap
|
|
2009
|
-
? 'support_v5_microtask_prompt_hard_cap'
|
|
2010
|
-
: promptTokenEstimate > cap
|
|
2011
|
-
? 'support_v5_microtask_prompt_soft_cap'
|
|
2012
|
-
: undefined
|
|
2013
|
-
};
|
|
2014
|
-
}
|
|
2015
|
-
|
|
2016
|
-
export function summarizeResolveIOSupportV5MicrotaskUsage(bundle: ResolveIOSupportV5StateBundle): {
|
|
2017
|
-
totalPromptTokenEstimate: number;
|
|
2018
|
-
byMicrotask: Array<{ microtaskId: string; promptTokenEstimate: number; calls: number }>;
|
|
2019
|
-
bySection: ResolveIOSupportV5UsageSection[];
|
|
2020
|
-
broadPromptViolations: ResolveIOSupportV5MicrotaskUsage[];
|
|
2021
|
-
} {
|
|
2022
|
-
const byMicrotask = new Map<string, { microtaskId: string; promptTokenEstimate: number; calls: number }>();
|
|
2023
|
-
const bySection = new Map<string, number>();
|
|
2024
|
-
let totalPromptTokenEstimate = 0;
|
|
2025
|
-
const broadPromptViolations: ResolveIOSupportV5MicrotaskUsage[] = [];
|
|
2026
|
-
const promptBudget = buildResolveIOSupportV5PromptBudget();
|
|
2027
|
-
for (const usage of bundle.supportV5MicrotaskUsageHistory || []) {
|
|
2028
|
-
totalPromptTokenEstimate += usage.promptTokenEstimate || 0;
|
|
2029
|
-
const existing = byMicrotask.get(usage.microtaskId) || { microtaskId: usage.microtaskId, promptTokenEstimate: 0, calls: 0 };
|
|
2030
|
-
existing.promptTokenEstimate += usage.promptTokenEstimate || 0;
|
|
2031
|
-
existing.calls += 1;
|
|
2032
|
-
byMicrotask.set(usage.microtaskId, existing);
|
|
2033
|
-
for (const section of usage.promptSections || []) {
|
|
2034
|
-
bySection.set(section.name, (bySection.get(section.name) || 0) + section.tokenEstimate);
|
|
2035
|
-
}
|
|
2036
|
-
const hardCap = usage.lane === 'qa' ? promptBudget.qaMicrotaskHardCap : promptBudget.buildMicrotaskHardCap;
|
|
2037
|
-
if ((usage.promptTokenEstimate || 0) > hardCap) {
|
|
2038
|
-
broadPromptViolations.push(usage);
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
2041
|
-
return {
|
|
2042
|
-
totalPromptTokenEstimate,
|
|
2043
|
-
byMicrotask: Array.from(byMicrotask.values()),
|
|
2044
|
-
bySection: Array.from(bySection.entries()).map(([name, tokenEstimate]) => ({ name, tokenEstimate })),
|
|
2045
|
-
broadPromptViolations
|
|
2046
|
-
};
|
|
2047
|
-
}
|
|
2048
|
-
|
|
2049
|
-
export function buildResolveIOSupportV5Incident(input: {
|
|
2050
|
-
incidentClass: string;
|
|
2051
|
-
summary: string;
|
|
2052
|
-
stepType?: ResolveIOSupportV5StepType;
|
|
2053
|
-
blocker?: string;
|
|
2054
|
-
artifactPaths?: string[];
|
|
2055
|
-
now?: Date | string;
|
|
2056
|
-
}): ResolveIOSupportV5RunnerIncident {
|
|
2057
|
-
return {
|
|
2058
|
-
incidentClass: cleanText(input.incidentClass, 120) || 'support_v5_runner_incident',
|
|
2059
|
-
summary: cleanText(input.summary, 1200),
|
|
2060
|
-
stepType: input.stepType,
|
|
2061
|
-
blockerFingerprint: input.blocker ? fingerprintResolveIOSupportV5Blocker(input.blocker) : undefined,
|
|
2062
|
-
artifactPaths: cleanList(input.artifactPaths, 40, 500),
|
|
2063
|
-
recordedAt: isoNow(input.now)
|
|
2064
|
-
};
|
|
2065
|
-
}
|