patchwork-os 0.2.0-beta.9.canary.93 → 1.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.bridge.md +15 -16
- package/README.md +46 -458
- package/dist/activationMetrics.js +2 -3
- package/dist/activationMetrics.js.map +1 -1
- package/dist/activityLog.d.ts +1 -0
- package/dist/activityLog.js +8 -3
- package/dist/activityLog.js.map +1 -1
- package/dist/adapters/gemini.js +2 -2
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/grok.js +6 -1
- package/dist/adapters/grok.js.map +1 -1
- package/dist/adapters/openai.js +4 -0
- package/dist/adapters/openai.js.map +1 -1
- package/dist/approvalHttp.d.ts +9 -0
- package/dist/approvalHttp.js +210 -171
- package/dist/approvalHttp.js.map +1 -1
- package/dist/approvalKpi.d.ts +102 -0
- package/dist/approvalKpi.js +282 -0
- package/dist/approvalKpi.js.map +1 -0
- package/dist/approvalQueue.d.ts +1 -1
- package/dist/approvalQueue.js.map +1 -1
- package/dist/automation.d.ts +45 -4
- package/dist/automation.js +123 -15
- package/dist/automation.js.map +1 -1
- package/dist/bridge.d.ts +10 -0
- package/dist/bridge.js +225 -46
- package/dist/bridge.js.map +1 -1
- package/dist/bridgeLockDiscovery.d.ts +16 -1
- package/dist/bridgeLockDiscovery.js +38 -4
- package/dist/bridgeLockDiscovery.js.map +1 -1
- package/dist/bridgeToolsRules.js +3 -18
- package/dist/bridgeToolsRules.js.map +1 -1
- package/dist/claudeAuthHttp.d.ts +25 -0
- package/dist/claudeAuthHttp.js +219 -0
- package/dist/claudeAuthHttp.js.map +1 -0
- package/dist/claudeDriver.js +4 -1
- package/dist/claudeDriver.js.map +1 -1
- package/dist/claudeOrchestrator.d.ts +15 -0
- package/dist/claudeOrchestrator.js +44 -0
- package/dist/claudeOrchestrator.js.map +1 -1
- package/dist/commands/connect.d.ts +47 -0
- package/dist/commands/connect.js +419 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/install.js +3 -10
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/launchd.d.ts +7 -0
- package/dist/commands/launchd.js +20 -2
- package/dist/commands/launchd.js.map +1 -1
- package/dist/commands/patchworkInit.d.ts +7 -0
- package/dist/commands/patchworkInit.js +26 -0
- package/dist/commands/patchworkInit.js.map +1 -1
- package/dist/commands/recipe.d.ts +59 -4
- package/dist/commands/recipe.js +206 -5
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/recipeInstall.d.ts +9 -0
- package/dist/commands/recipeInstall.js +56 -3
- package/dist/commands/recipeInstall.js.map +1 -1
- package/dist/commands/task.d.ts +25 -0
- package/dist/commands/task.js +61 -41
- package/dist/commands/task.js.map +1 -1
- package/dist/commands/tokenEfficiency.d.ts +4 -0
- package/dist/commands/tokenEfficiency.js +23 -26
- package/dist/commands/tokenEfficiency.js.map +1 -1
- package/dist/commands/tracesExport.d.ts +15 -1
- package/dist/commands/tracesExport.js +39 -5
- package/dist/commands/tracesExport.js.map +1 -1
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -1
- package/dist/connectorRoutes.js +613 -62
- package/dist/connectorRoutes.js.map +1 -1
- package/dist/connectors/asana.js +9 -3
- package/dist/connectors/asana.js.map +1 -1
- package/dist/connectors/baseConnector.d.ts +16 -0
- package/dist/connectors/baseConnector.js +2 -0
- package/dist/connectors/baseConnector.js.map +1 -1
- package/dist/connectors/caldiy.js +34 -0
- package/dist/connectors/caldiy.js.map +1 -1
- package/dist/connectors/confluence.js +9 -2
- package/dist/connectors/confluence.js.map +1 -1
- package/dist/connectors/connectorActivity.d.ts +24 -0
- package/dist/connectors/connectorActivity.js +32 -0
- package/dist/connectors/connectorActivity.js.map +1 -0
- package/dist/connectors/connectorRedirectUri.js +22 -2
- package/dist/connectors/connectorRedirectUri.js.map +1 -1
- package/dist/connectors/connectorRegistry.d.ts +0 -3
- package/dist/connectors/connectorRegistry.js +8 -8
- package/dist/connectors/connectorRegistry.js.map +1 -1
- package/dist/connectors/datadog.js +8 -1
- package/dist/connectors/datadog.js.map +1 -1
- package/dist/connectors/discord.js +4 -3
- package/dist/connectors/discord.js.map +1 -1
- package/dist/connectors/elasticsearch.js +22 -0
- package/dist/connectors/elasticsearch.js.map +1 -1
- package/dist/connectors/github.d.ts +38 -0
- package/dist/connectors/github.js +91 -5
- package/dist/connectors/github.js.map +1 -1
- package/dist/connectors/gitlab.js +19 -16
- package/dist/connectors/gitlab.js.map +1 -1
- package/dist/connectors/gmail.d.ts +5 -0
- package/dist/connectors/gmail.js +53 -11
- package/dist/connectors/gmail.js.map +1 -1
- package/dist/connectors/googleCalendar.js +5 -4
- package/dist/connectors/googleCalendar.js.map +1 -1
- package/dist/connectors/googleDocs.js +7 -6
- package/dist/connectors/googleDocs.js.map +1 -1
- package/dist/connectors/googleDrive.js +15 -8
- package/dist/connectors/googleDrive.js.map +1 -1
- package/dist/connectors/grafana.js +39 -3
- package/dist/connectors/grafana.js.map +1 -1
- package/dist/connectors/jira.d.ts +1 -1
- package/dist/connectors/jira.js +19 -4
- package/dist/connectors/jira.js.map +1 -1
- package/dist/connectors/linear.js +2 -2
- package/dist/connectors/linear.js.map +1 -1
- package/dist/connectors/mcpClient.d.ts +29 -1
- package/dist/connectors/mcpClient.js +114 -44
- package/dist/connectors/mcpClient.js.map +1 -1
- package/dist/connectors/mcpOAuth.d.ts +1 -0
- package/dist/connectors/mcpOAuth.js +49 -4
- package/dist/connectors/mcpOAuth.js.map +1 -1
- package/dist/connectors/monday.js +5 -4
- package/dist/connectors/monday.js.map +1 -1
- package/dist/connectors/mongodb.js +32 -5
- package/dist/connectors/mongodb.js.map +1 -1
- package/dist/connectors/notion.d.ts +1 -1
- package/dist/connectors/notion.js +22 -6
- package/dist/connectors/notion.js.map +1 -1
- package/dist/connectors/oauthError.d.ts +17 -0
- package/dist/connectors/oauthError.js +50 -0
- package/dist/connectors/oauthError.js.map +1 -0
- package/dist/connectors/postgres.d.ts +7 -0
- package/dist/connectors/postgres.js +32 -2
- package/dist/connectors/postgres.js.map +1 -1
- package/dist/connectors/posthog.js +26 -0
- package/dist/connectors/posthog.js.map +1 -1
- package/dist/connectors/redis.d.ts +1 -0
- package/dist/connectors/redis.js +47 -20
- package/dist/connectors/redis.js.map +1 -1
- package/dist/connectors/salesforce.js +66 -5
- package/dist/connectors/salesforce.js.map +1 -1
- package/dist/connectors/sentry.js +2 -2
- package/dist/connectors/sentry.js.map +1 -1
- package/dist/connectors/slack.js +37 -14
- package/dist/connectors/slack.js.map +1 -1
- package/dist/connectors/snowflake.js +24 -0
- package/dist/connectors/snowflake.js.map +1 -1
- package/dist/connectors/stripe.js +9 -2
- package/dist/connectors/stripe.js.map +1 -1
- package/dist/connectors/supabase.js +34 -0
- package/dist/connectors/supabase.js.map +1 -1
- package/dist/connectors/tokenStorage.d.ts +20 -0
- package/dist/connectors/tokenStorage.js +196 -64
- package/dist/connectors/tokenStorage.js.map +1 -1
- package/dist/connectors/woocommerce.js +34 -0
- package/dist/connectors/woocommerce.js.map +1 -1
- package/dist/copilot/parseIntent.d.ts +58 -0
- package/dist/copilot/parseIntent.js +149 -0
- package/dist/copilot/parseIntent.js.map +1 -0
- package/dist/decisionReplay.d.ts +8 -6
- package/dist/decisionReplay.js +35 -11
- package/dist/decisionReplay.js.map +1 -1
- package/dist/decisionTraceLog.d.ts +9 -0
- package/dist/decisionTraceLog.js +6 -0
- package/dist/decisionTraceLog.js.map +1 -1
- package/dist/drivers/claude/api.js +49 -7
- package/dist/drivers/claude/api.js.map +1 -1
- package/dist/drivers/claude/envSanitizer.d.ts +9 -1
- package/dist/drivers/claude/envSanitizer.js +41 -3
- package/dist/drivers/claude/envSanitizer.js.map +1 -1
- package/dist/drivers/claude/streamParser.d.ts +13 -0
- package/dist/drivers/claude/streamParser.js.map +1 -1
- package/dist/drivers/claude/subprocess.js +131 -16
- package/dist/drivers/claude/subprocess.js.map +1 -1
- package/dist/drivers/claude/subprocessSettings.d.ts +1 -1
- package/dist/drivers/claude/subprocessSettings.js +18 -4
- package/dist/drivers/claude/subprocessSettings.js.map +1 -1
- package/dist/drivers/gemini/index.d.ts +13 -0
- package/dist/drivers/gemini/index.js +211 -67
- package/dist/drivers/gemini/index.js.map +1 -1
- package/dist/drivers/local/index.d.ts +2 -17
- package/dist/drivers/local/index.js +5 -92
- package/dist/drivers/local/index.js.map +1 -1
- package/dist/drivers/openai/index.js +69 -9
- package/dist/drivers/openai/index.js.map +1 -1
- package/dist/drivers/outputCap.d.ts +27 -0
- package/dist/drivers/outputCap.js +50 -0
- package/dist/drivers/outputCap.js.map +1 -0
- package/dist/embeddings/cosine.d.ts +23 -0
- package/dist/embeddings/cosine.js +59 -0
- package/dist/embeddings/cosine.js.map +1 -0
- package/dist/embeddings/index.d.ts +19 -0
- package/dist/embeddings/index.js +35 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/localEmbeddings.d.ts +29 -0
- package/dist/embeddings/localEmbeddings.js +103 -0
- package/dist/embeddings/localEmbeddings.js.map +1 -0
- package/dist/embeddings/localEndpoints.d.ts +24 -0
- package/dist/embeddings/localEndpoints.js +37 -0
- package/dist/embeddings/localEndpoints.js.map +1 -0
- package/dist/embeddings/types.d.ts +32 -0
- package/dist/embeddings/types.js +12 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/featureFlags.d.ts +18 -0
- package/dist/featureFlags.js +32 -0
- package/dist/featureFlags.js.map +1 -1
- package/dist/fp/automationInterpreter.js +118 -39
- package/dist/fp/automationInterpreter.js.map +1 -1
- package/dist/fp/automationProgram.d.ts +10 -0
- package/dist/fp/automationProgram.js.map +1 -1
- package/dist/fp/automationState.d.ts +6 -0
- package/dist/fp/automationState.js +38 -0
- package/dist/fp/automationState.js.map +1 -1
- package/dist/fp/commandDescription.d.ts +6 -0
- package/dist/fp/commandDescription.js +18 -5
- package/dist/fp/commandDescription.js.map +1 -1
- package/dist/fp/interpreterContext.d.ts +16 -5
- package/dist/fp/interpreterContext.js +59 -3
- package/dist/fp/interpreterContext.js.map +1 -1
- package/dist/fp/policyParser.js +18 -8
- package/dist/fp/policyParser.js.map +1 -1
- package/dist/haltPushDispatch.d.ts +4 -0
- package/dist/haltPushDispatch.js +7 -22
- package/dist/haltPushDispatch.js.map +1 -1
- package/dist/inboxRoutes.js +2 -2
- package/dist/inboxRoutes.js.map +1 -1
- package/dist/index.js +672 -135
- package/dist/index.js.map +1 -1
- package/dist/installGuard.js +6 -0
- package/dist/installGuard.js.map +1 -1
- package/dist/localEndpointGuard.d.ts +25 -0
- package/dist/localEndpointGuard.js +101 -0
- package/dist/localEndpointGuard.js.map +1 -0
- package/dist/mcpRoutes.js +1 -1
- package/dist/mcpRoutes.js.map +1 -1
- package/dist/oauth.d.ts +13 -0
- package/dist/oauth.js +53 -9
- package/dist/oauth.js.map +1 -1
- package/dist/orchestrator/childBridgeClient.d.ts +7 -0
- package/dist/orchestrator/childBridgeClient.js +42 -1
- package/dist/orchestrator/childBridgeClient.js.map +1 -1
- package/dist/orchestrator/orchestratorBridge.d.ts +33 -0
- package/dist/orchestrator/orchestratorBridge.js +75 -9
- package/dist/orchestrator/orchestratorBridge.js.map +1 -1
- package/dist/patchworkConfig.d.ts +4 -0
- package/dist/patchworkConfig.js +33 -4
- package/dist/patchworkConfig.js.map +1 -1
- package/dist/probe.js +39 -5
- package/dist/probe.js.map +1 -1
- package/dist/recipeOrchestration.d.ts +59 -0
- package/dist/recipeOrchestration.js +314 -60
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipeRoutes.d.ts +93 -0
- package/dist/recipeRoutes.js +664 -27
- package/dist/recipeRoutes.js.map +1 -1
- package/dist/recipes/RecipeOrchestrator.d.ts +14 -0
- package/dist/recipes/RecipeOrchestrator.js +42 -2
- package/dist/recipes/RecipeOrchestrator.js.map +1 -1
- package/dist/recipes/agentExecutor.d.ts +51 -2
- package/dist/recipes/agentExecutor.js +86 -13
- package/dist/recipes/agentExecutor.js.map +1 -1
- package/dist/recipes/chainedRunner.d.ts +111 -3
- package/dist/recipes/chainedRunner.js +440 -45
- package/dist/recipes/chainedRunner.js.map +1 -1
- package/dist/recipes/compiler.js +42 -29
- package/dist/recipes/compiler.js.map +1 -1
- package/dist/recipes/connectorPreflight.js +31 -0
- package/dist/recipes/connectorPreflight.js.map +1 -1
- package/dist/recipes/dependencyGraph.d.ts +16 -0
- package/dist/recipes/dependencyGraph.js +37 -2
- package/dist/recipes/dependencyGraph.js.map +1 -1
- package/dist/recipes/eventTriggerPrograms.d.ts +36 -0
- package/dist/recipes/eventTriggerPrograms.js +158 -0
- package/dist/recipes/eventTriggerPrograms.js.map +1 -0
- package/dist/recipes/githubInstallSource.d.ts +9 -2
- package/dist/recipes/githubInstallSource.js +36 -6
- package/dist/recipes/githubInstallSource.js.map +1 -1
- package/dist/recipes/haltCategory.d.ts +10 -0
- package/dist/recipes/haltCategory.js +11 -1
- package/dist/recipes/haltCategory.js.map +1 -1
- package/dist/recipes/idempotencyKey.d.ts +30 -3
- package/dist/recipes/idempotencyKey.js +89 -5
- package/dist/recipes/idempotencyKey.js.map +1 -1
- package/dist/recipes/installer.js +12 -35
- package/dist/recipes/installer.js.map +1 -1
- package/dist/recipes/judgeVerdict.d.ts +11 -1
- package/dist/recipes/judgeVerdict.js +47 -7
- package/dist/recipes/judgeVerdict.js.map +1 -1
- package/dist/recipes/names.d.ts +5 -0
- package/dist/recipes/names.js +10 -5
- package/dist/recipes/names.js.map +1 -1
- package/dist/recipes/parser.js +74 -10
- package/dist/recipes/parser.js.map +1 -1
- package/dist/recipes/pricing/costRouter.d.ts +43 -0
- package/dist/recipes/pricing/costRouter.js +44 -0
- package/dist/recipes/pricing/costRouter.js.map +1 -0
- package/dist/recipes/pricing/priceTable.d.ts +76 -0
- package/dist/recipes/pricing/priceTable.js +144 -0
- package/dist/recipes/pricing/priceTable.js.map +1 -0
- package/dist/recipes/replayRun.js +5 -2
- package/dist/recipes/replayRun.js.map +1 -1
- package/dist/recipes/resolveRecipePath.js +15 -1
- package/dist/recipes/resolveRecipePath.js.map +1 -1
- package/dist/recipes/runBudget.d.ts +93 -32
- package/dist/recipes/runBudget.js +213 -49
- package/dist/recipes/runBudget.js.map +1 -1
- package/dist/recipes/runRegistry.d.ts +32 -0
- package/dist/recipes/runRegistry.js +54 -0
- package/dist/recipes/runRegistry.js.map +1 -0
- package/dist/recipes/scheduler.js +6 -2
- package/dist/recipes/scheduler.js.map +1 -1
- package/dist/recipes/schema.d.ts +59 -6
- package/dist/recipes/schemaGenerator.d.ts +9 -0
- package/dist/recipes/schemaGenerator.js +446 -77
- package/dist/recipes/schemaGenerator.js.map +1 -1
- package/dist/recipes/simulation/aggregateRunRisk.d.ts +46 -0
- package/dist/recipes/simulation/aggregateRunRisk.js +120 -0
- package/dist/recipes/simulation/aggregateRunRisk.js.map +1 -0
- package/dist/recipes/simulation/costProjector.d.ts +32 -0
- package/dist/recipes/simulation/costProjector.js +194 -0
- package/dist/recipes/simulation/costProjector.js.map +1 -0
- package/dist/recipes/simulation/sideEffects.d.ts +32 -0
- package/dist/recipes/simulation/sideEffects.js +62 -0
- package/dist/recipes/simulation/sideEffects.js.map +1 -0
- package/dist/recipes/simulation/simulate.d.ts +36 -0
- package/dist/recipes/simulation/simulate.js +264 -0
- package/dist/recipes/simulation/simulate.js.map +1 -0
- package/dist/recipes/simulation/simulateMockedRun.d.ts +52 -0
- package/dist/recipes/simulation/simulateMockedRun.js +84 -0
- package/dist/recipes/simulation/simulateMockedRun.js.map +1 -0
- package/dist/recipes/simulation/synthesizeMockedOutputs.d.ts +31 -0
- package/dist/recipes/simulation/synthesizeMockedOutputs.js +50 -0
- package/dist/recipes/simulation/synthesizeMockedOutputs.js.map +1 -0
- package/dist/recipes/simulation/types.d.ts +198 -0
- package/dist/recipes/simulation/types.js +30 -0
- package/dist/recipes/simulation/types.js.map +1 -0
- package/dist/recipes/stepObservation.d.ts +12 -0
- package/dist/recipes/stepObservation.js +21 -1
- package/dist/recipes/stepObservation.js.map +1 -1
- package/dist/recipes/toolRegistry.js +61 -24
- package/dist/recipes/toolRegistry.js.map +1 -1
- package/dist/recipes/tools/airtable.d.ts +15 -0
- package/dist/recipes/tools/airtable.js +240 -0
- package/dist/recipes/tools/airtable.js.map +1 -0
- package/dist/recipes/tools/caldiy.d.ts +13 -0
- package/dist/recipes/tools/caldiy.js +215 -0
- package/dist/recipes/tools/caldiy.js.map +1 -0
- package/dist/recipes/tools/circleci.d.ts +10 -0
- package/dist/recipes/tools/circleci.js +204 -0
- package/dist/recipes/tools/circleci.js.map +1 -0
- package/dist/recipes/tools/cloudflare.d.ts +13 -0
- package/dist/recipes/tools/cloudflare.js +211 -0
- package/dist/recipes/tools/cloudflare.js.map +1 -0
- package/dist/recipes/tools/confluence.js +11 -10
- package/dist/recipes/tools/confluence.js.map +1 -1
- package/dist/recipes/tools/datadog.js +13 -12
- package/dist/recipes/tools/datadog.js.map +1 -1
- package/dist/recipes/tools/docs.d.ts +18 -0
- package/dist/recipes/tools/docs.js +95 -0
- package/dist/recipes/tools/docs.js.map +1 -0
- package/dist/recipes/tools/elasticsearch.d.ts +11 -0
- package/dist/recipes/tools/elasticsearch.js +157 -0
- package/dist/recipes/tools/elasticsearch.js.map +1 -0
- package/dist/recipes/tools/fanOut.js +4 -4
- package/dist/recipes/tools/fanOut.js.map +1 -1
- package/dist/recipes/tools/figma.d.ts +12 -0
- package/dist/recipes/tools/figma.js +195 -0
- package/dist/recipes/tools/figma.js.map +1 -0
- package/dist/recipes/tools/file.js +43 -22
- package/dist/recipes/tools/file.js.map +1 -1
- package/dist/recipes/tools/github.js +162 -5
- package/dist/recipes/tools/github.js.map +1 -1
- package/dist/recipes/tools/gmail.js +45 -33
- package/dist/recipes/tools/gmail.js.map +1 -1
- package/dist/recipes/tools/grafana.d.ts +11 -0
- package/dist/recipes/tools/grafana.js +216 -0
- package/dist/recipes/tools/grafana.js.map +1 -0
- package/dist/recipes/tools/http.d.ts +1 -1
- package/dist/recipes/tools/http.js +10 -28
- package/dist/recipes/tools/http.js.map +1 -1
- package/dist/recipes/tools/hubspot.js +13 -12
- package/dist/recipes/tools/hubspot.js.map +1 -1
- package/dist/recipes/tools/index.d.ts +28 -0
- package/dist/recipes/tools/index.js +28 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/intercom.js +11 -10
- package/dist/recipes/tools/intercom.js.map +1 -1
- package/dist/recipes/tools/jira.js +13 -0
- package/dist/recipes/tools/jira.js.map +1 -1
- package/dist/recipes/tools/meetingNotes.js +2 -2
- package/dist/recipes/tools/monday.d.ts +22 -0
- package/dist/recipes/tools/monday.js +242 -0
- package/dist/recipes/tools/monday.js.map +1 -0
- package/dist/recipes/tools/mongodb.d.ts +19 -0
- package/dist/recipes/tools/mongodb.js +194 -0
- package/dist/recipes/tools/mongodb.js.map +1 -0
- package/dist/recipes/tools/notion.js +11 -10
- package/dist/recipes/tools/notion.js.map +1 -1
- package/dist/recipes/tools/obsidian.d.ts +15 -0
- package/dist/recipes/tools/obsidian.js +173 -0
- package/dist/recipes/tools/obsidian.js.map +1 -0
- package/dist/recipes/tools/outcomes.d.ts +15 -0
- package/dist/recipes/tools/outcomes.js +111 -0
- package/dist/recipes/tools/outcomes.js.map +1 -0
- package/dist/recipes/tools/paystack.d.ts +11 -0
- package/dist/recipes/tools/paystack.js +212 -0
- package/dist/recipes/tools/paystack.js.map +1 -0
- package/dist/recipes/tools/pipedrive.d.ts +16 -0
- package/dist/recipes/tools/pipedrive.js +234 -0
- package/dist/recipes/tools/pipedrive.js.map +1 -0
- package/dist/recipes/tools/postgres.d.ts +15 -0
- package/dist/recipes/tools/postgres.js +186 -0
- package/dist/recipes/tools/postgres.js.map +1 -0
- package/dist/recipes/tools/posthog.d.ts +16 -0
- package/dist/recipes/tools/posthog.js +219 -0
- package/dist/recipes/tools/posthog.js.map +1 -0
- package/dist/recipes/tools/redis.d.ts +9 -0
- package/dist/recipes/tools/redis.js +141 -0
- package/dist/recipes/tools/redis.js.map +1 -0
- package/dist/recipes/tools/resend.d.ts +8 -0
- package/dist/recipes/tools/resend.js +153 -0
- package/dist/recipes/tools/resend.js.map +1 -0
- package/dist/recipes/tools/salesforce.d.ts +16 -0
- package/dist/recipes/tools/salesforce.js +184 -0
- package/dist/recipes/tools/salesforce.js.map +1 -0
- package/dist/recipes/tools/sendgrid.d.ts +9 -0
- package/dist/recipes/tools/sendgrid.js +175 -0
- package/dist/recipes/tools/sendgrid.js.map +1 -0
- package/dist/recipes/tools/shopify.d.ts +16 -0
- package/dist/recipes/tools/shopify.js +266 -0
- package/dist/recipes/tools/shopify.js.map +1 -0
- package/dist/recipes/tools/snowflake.d.ts +16 -0
- package/dist/recipes/tools/snowflake.js +173 -0
- package/dist/recipes/tools/snowflake.js.map +1 -0
- package/dist/recipes/tools/stripe.js +13 -12
- package/dist/recipes/tools/stripe.js.map +1 -1
- package/dist/recipes/tools/supabase.d.ts +9 -0
- package/dist/recipes/tools/supabase.js +133 -0
- package/dist/recipes/tools/supabase.js.map +1 -0
- package/dist/recipes/tools/todoist.d.ts +15 -0
- package/dist/recipes/tools/todoist.js +228 -0
- package/dist/recipes/tools/todoist.js.map +1 -0
- package/dist/recipes/tools/twilio.d.ts +11 -0
- package/dist/recipes/tools/twilio.js +180 -0
- package/dist/recipes/tools/twilio.js.map +1 -0
- package/dist/recipes/tools/vercel.d.ts +9 -0
- package/dist/recipes/tools/vercel.js +146 -0
- package/dist/recipes/tools/vercel.js.map +1 -0
- package/dist/recipes/tools/webflow.d.ts +11 -0
- package/dist/recipes/tools/webflow.js +244 -0
- package/dist/recipes/tools/webflow.js.map +1 -0
- package/dist/recipes/tools/woocommerce.d.ts +18 -0
- package/dist/recipes/tools/woocommerce.js +260 -0
- package/dist/recipes/tools/woocommerce.js.map +1 -0
- package/dist/recipes/tools/wrapConnectorExecute.d.ts +25 -0
- package/dist/recipes/tools/wrapConnectorExecute.js +37 -0
- package/dist/recipes/tools/wrapConnectorExecute.js.map +1 -0
- package/dist/recipes/tools/zendesk.js +11 -10
- package/dist/recipes/tools/zendesk.js.map +1 -1
- package/dist/recipes/triggerVars.d.ts +15 -0
- package/dist/recipes/triggerVars.js +57 -0
- package/dist/recipes/triggerVars.js.map +1 -0
- package/dist/recipes/validation.d.ts +1 -1
- package/dist/recipes/validation.js +536 -12
- package/dist/recipes/validation.js.map +1 -1
- package/dist/recipes/yamlPositions.d.ts +1 -1
- package/dist/recipes/yamlPositions.js +7 -2
- package/dist/recipes/yamlPositions.js.map +1 -1
- package/dist/recipes/yamlRunner.d.ts +216 -4
- package/dist/recipes/yamlRunner.js +1030 -96
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +5 -0
- package/dist/recipesHttp.js +68 -6
- package/dist/recipesHttp.js.map +1 -1
- package/dist/resources.js +14 -1
- package/dist/resources.js.map +1 -1
- package/dist/riskSignals.d.ts +42 -0
- package/dist/riskSignals.js +197 -0
- package/dist/riskSignals.js.map +1 -0
- package/dist/riskTier.d.ts +9 -0
- package/dist/riskTier.js +48 -0
- package/dist/riskTier.js.map +1 -1
- package/dist/runLog.d.ts +53 -0
- package/dist/runLog.js +75 -16
- package/dist/runLog.js.map +1 -1
- package/dist/schemas/recipe.v1.json +360 -16
- package/dist/server.d.ts +60 -0
- package/dist/server.js +192 -31
- package/dist/server.js.map +1 -1
- package/dist/sessionCheckpoint.js +4 -1
- package/dist/sessionCheckpoint.js.map +1 -1
- package/dist/sessionDetail.d.ts +43 -0
- package/dist/sessionDetail.js +59 -0
- package/dist/sessionDetail.js.map +1 -0
- package/dist/settingsEnv.d.ts +47 -0
- package/dist/settingsEnv.js +88 -0
- package/dist/settingsEnv.js.map +1 -0
- package/dist/streamableHttp.js +44 -10
- package/dist/streamableHttp.js.map +1 -1
- package/dist/ta/backtest/abnday.d.ts +53 -0
- package/dist/ta/backtest/abnday.js +123 -0
- package/dist/ta/backtest/abnday.js.map +1 -0
- package/dist/ta/backtest/directional.d.ts +48 -0
- package/dist/ta/backtest/directional.js +103 -0
- package/dist/ta/backtest/directional.js.map +1 -0
- package/dist/ta/backtest/fundx.d.ts +67 -0
- package/dist/ta/backtest/fundx.js +264 -0
- package/dist/ta/backtest/fundx.js.map +1 -0
- package/dist/ta/backtest/fvg.d.ts +62 -0
- package/dist/ta/backtest/fvg.js +236 -0
- package/dist/ta/backtest/fvg.js.map +1 -0
- package/dist/ta/backtest/ichimoku.d.ts +41 -0
- package/dist/ta/backtest/ichimoku.js +146 -0
- package/dist/ta/backtest/ichimoku.js.map +1 -0
- package/dist/ta/backtest/ingest.d.ts +20 -0
- package/dist/ta/backtest/ingest.js +104 -0
- package/dist/ta/backtest/ingest.js.map +1 -0
- package/dist/ta/backtest/msb.d.ts +49 -0
- package/dist/ta/backtest/msb.js +162 -0
- package/dist/ta/backtest/msb.js.map +1 -0
- package/dist/ta/backtest/scoring.d.ts +33 -0
- package/dist/ta/backtest/scoring.js +82 -0
- package/dist/ta/backtest/scoring.js.map +1 -0
- package/dist/ta/backtest/summary.d.ts +20 -0
- package/dist/ta/backtest/summary.js +42 -0
- package/dist/ta/backtest/summary.js.map +1 -0
- package/dist/ta/backtest/tsmom.d.ts +72 -0
- package/dist/ta/backtest/tsmom.js +202 -0
- package/dist/ta/backtest/tsmom.js.map +1 -0
- package/dist/ta/backtest/volsq.d.ts +34 -0
- package/dist/ta/backtest/volsq.js +154 -0
- package/dist/ta/backtest/volsq.js.map +1 -0
- package/dist/ta/backtest/walkForward.d.ts +45 -0
- package/dist/ta/backtest/walkForward.js +136 -0
- package/dist/ta/backtest/walkForward.js.map +1 -0
- package/dist/ta/cycles.d.ts +15 -0
- package/dist/ta/cycles.js +31 -0
- package/dist/ta/cycles.js.map +1 -0
- package/dist/ta/desk/accrualEmitter.d.ts +59 -0
- package/dist/ta/desk/accrualEmitter.js +136 -0
- package/dist/ta/desk/accrualEmitter.js.map +1 -0
- package/dist/ta/desk/cellBacktest.d.ts +179 -0
- package/dist/ta/desk/cellBacktest.js +514 -0
- package/dist/ta/desk/cellBacktest.js.map +1 -0
- package/dist/ta/desk/cells/wpMaRejection.d.ts +49 -0
- package/dist/ta/desk/cells/wpMaRejection.js +141 -0
- package/dist/ta/desk/cells/wpMaRejection.js.map +1 -0
- package/dist/ta/desk/cells/wpVolumeClimax.d.ts +57 -0
- package/dist/ta/desk/cells/wpVolumeClimax.js +193 -0
- package/dist/ta/desk/cells/wpVolumeClimax.js.map +1 -0
- package/dist/ta/desk/collectors.d.ts +18 -0
- package/dist/ta/desk/collectors.js +450 -0
- package/dist/ta/desk/collectors.js.map +1 -0
- package/dist/ta/desk/contract.d.ts +51 -0
- package/dist/ta/desk/contract.js +261 -0
- package/dist/ta/desk/contract.js.map +1 -0
- package/dist/ta/desk/deskLedger.d.ts +36 -0
- package/dist/ta/desk/deskLedger.js +239 -0
- package/dist/ta/desk/deskLedger.js.map +1 -0
- package/dist/ta/desk/liqTape.d.ts +37 -0
- package/dist/ta/desk/liqTape.js +99 -0
- package/dist/ta/desk/liqTape.js.map +1 -0
- package/dist/ta/desk/post.d.ts +20 -0
- package/dist/ta/desk/post.js +65 -0
- package/dist/ta/desk/post.js.map +1 -0
- package/dist/ta/desk/render.d.ts +25 -0
- package/dist/ta/desk/render.js +398 -0
- package/dist/ta/desk/render.js.map +1 -0
- package/dist/ta/desk/surfaces.d.ts +216 -0
- package/dist/ta/desk/surfaces.js +472 -0
- package/dist/ta/desk/surfaces.js.map +1 -0
- package/dist/ta/desk/types.d.ts +174 -0
- package/dist/ta/desk/types.js +104 -0
- package/dist/ta/desk/types.js.map +1 -0
- package/dist/ta/index.d.ts +23 -0
- package/dist/ta/index.js +54 -0
- package/dist/ta/index.js.map +1 -0
- package/dist/ta/ledger.d.ts +44 -0
- package/dist/ta/ledger.js +95 -0
- package/dist/ta/ledger.js.map +1 -0
- package/dist/ta/levels.d.ts +21 -0
- package/dist/ta/levels.js +41 -0
- package/dist/ta/levels.js.map +1 -0
- package/dist/ta/swings.d.ts +30 -0
- package/dist/ta/swings.js +83 -0
- package/dist/ta/swings.js.map +1 -0
- package/dist/ta/types.d.ts +81 -0
- package/dist/ta/types.js +20 -0
- package/dist/ta/types.js.map +1 -0
- package/dist/telemetry.js +20 -9
- package/dist/telemetry.js.map +1 -1
- package/dist/tokenUsageTracker.d.ts +2 -1
- package/dist/tokenUsageTracker.js +38 -20
- package/dist/tokenUsageTracker.js.map +1 -1
- package/dist/tools/contextBundle.js +13 -9
- package/dist/tools/contextBundle.js.map +1 -1
- package/dist/tools/ctxGetTaskContext.js +8 -3
- package/dist/tools/ctxGetTaskContext.js.map +1 -1
- package/dist/tools/ctxQueryTraces.d.ts +18 -1
- package/dist/tools/ctxQueryTraces.js +176 -27
- package/dist/tools/ctxQueryTraces.js.map +1 -1
- package/dist/tools/enrichCommit.js +5 -2
- package/dist/tools/enrichCommit.js.map +1 -1
- package/dist/tools/getDependencyTree.js +2 -2
- package/dist/tools/getDependencyTree.js.map +1 -1
- package/dist/tools/getDiagnostics.js +3 -0
- package/dist/tools/getDiagnostics.js.map +1 -1
- package/dist/tools/getDocumentSymbols.js +5 -1
- package/dist/tools/getDocumentSymbols.js.map +1 -1
- package/dist/tools/getGitHotspots.js +12 -1
- package/dist/tools/getGitHotspots.js.map +1 -1
- package/dist/tools/getGitLog.js +5 -2
- package/dist/tools/getGitLog.js.map +1 -1
- package/dist/tools/getGitStatus.js +6 -1
- package/dist/tools/getGitStatus.js.map +1 -1
- package/dist/tools/getProjectContext.js +3 -1
- package/dist/tools/getProjectContext.js.map +1 -1
- package/dist/tools/getToolCapabilities.js +39 -4
- package/dist/tools/getToolCapabilities.js.map +1 -1
- package/dist/tools/gitWrite.js +12 -3
- package/dist/tools/gitWrite.js.map +1 -1
- package/dist/tools/github/composite.d.ts +1 -1
- package/dist/tools/github/composite.js +7 -7
- package/dist/tools/github/composite.js.map +1 -1
- package/dist/tools/github/pr.d.ts +6 -6
- package/dist/tools/github/pr.js +18 -11
- package/dist/tools/github/pr.js.map +1 -1
- package/dist/tools/httpClient.js +55 -3
- package/dist/tools/httpClient.js.map +1 -1
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.js +19 -12
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lsp.d.ts +6 -0
- package/dist/tools/lsp.js +81 -12
- package/dist/tools/lsp.js.map +1 -1
- package/dist/tools/previewEdit.js +16 -1
- package/dist/tools/previewEdit.js.map +1 -1
- package/dist/tools/resumeClaudeTask.js +17 -0
- package/dist/tools/resumeClaudeTask.js.map +1 -1
- package/dist/tools/searchAndReplace.js +9 -5
- package/dist/tools/searchAndReplace.js.map +1 -1
- package/dist/tools/searchTools.d.ts +26 -0
- package/dist/tools/searchTools.js +42 -2
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/tools/terminal.js +23 -51
- package/dist/tools/terminal.js.map +1 -1
- package/dist/tools/transaction.d.ts +9 -1
- package/dist/tools/transaction.js +59 -4
- package/dist/tools/transaction.js.map +1 -1
- package/dist/tools/utils.d.ts +16 -0
- package/dist/tools/utils.js +77 -7
- package/dist/tools/utils.js.map +1 -1
- package/dist/transport.d.ts +31 -0
- package/dist/transport.js +117 -14
- package/dist/transport.js.map +1 -1
- package/dist/wireHaltPushDispatch.js +12 -0
- package/dist/wireHaltPushDispatch.js.map +1 -1
- package/dist/workerGateDecisionLog.d.ts +141 -0
- package/dist/workerGateDecisionLog.js +361 -0
- package/dist/workerGateDecisionLog.js.map +1 -0
- package/dist/workers/actionClass.d.ts +38 -0
- package/dist/workers/actionClass.js +155 -0
- package/dist/workers/actionClass.js.map +1 -0
- package/dist/workers/backtest.d.ts +68 -0
- package/dist/workers/backtest.js +113 -0
- package/dist/workers/backtest.js.map +1 -0
- package/dist/workers/contextRisk.d.ts +35 -0
- package/dist/workers/contextRisk.js +20 -0
- package/dist/workers/contextRisk.js.map +1 -0
- package/dist/workers/contextRiskScorer.d.ts +48 -0
- package/dist/workers/contextRiskScorer.js +94 -0
- package/dist/workers/contextRiskScorer.js.map +1 -0
- package/dist/workers/graduation.d.ts +61 -0
- package/dist/workers/graduation.js +112 -0
- package/dist/workers/graduation.js.map +1 -0
- package/dist/workers/outcomeStore.d.ts +98 -0
- package/dist/workers/outcomeStore.js +146 -0
- package/dist/workers/outcomeStore.js.map +1 -0
- package/dist/workers/outcomesCli.d.ts +34 -0
- package/dist/workers/outcomesCli.js +91 -0
- package/dist/workers/outcomesCli.js.map +1 -0
- package/dist/workers/runWorkerShadow.d.ts +90 -0
- package/dist/workers/runWorkerShadow.js +323 -0
- package/dist/workers/runWorkerShadow.js.map +1 -0
- package/dist/workers/shadowGate.d.ts +30 -0
- package/dist/workers/shadowGate.js +58 -0
- package/dist/workers/shadowGate.js.map +1 -0
- package/dist/workers/shadowObserver.d.ts +165 -0
- package/dist/workers/shadowObserver.js +203 -0
- package/dist/workers/shadowObserver.js.map +1 -0
- package/dist/workers/shadowReport.d.ts +16 -0
- package/dist/workers/shadowReport.js +61 -0
- package/dist/workers/shadowReport.js.map +1 -0
- package/dist/workers/shadowRun.d.ts +38 -0
- package/dist/workers/shadowRun.js +44 -0
- package/dist/workers/shadowRun.js.map +1 -0
- package/dist/workers/trustLevel.d.ts +82 -0
- package/dist/workers/trustLevel.js +100 -0
- package/dist/workers/trustLevel.js.map +1 -0
- package/dist/workers/worker.d.ts +49 -0
- package/dist/workers/worker.js +88 -0
- package/dist/workers/worker.js.map +1 -0
- package/dist/workers/workerGate.d.ts +101 -0
- package/dist/workers/workerGate.js +210 -0
- package/dist/workers/workerGate.js.map +1 -0
- package/dist/workers/workerLevelStore.d.ts +33 -0
- package/dist/workers/workerLevelStore.js +87 -0
- package/dist/workers/workerLevelStore.js.map +1 -0
- package/dist/workers/workerLoader.d.ts +7 -0
- package/dist/workers/workerLoader.js +31 -0
- package/dist/workers/workerLoader.js.map +1 -0
- package/dist/writeFileAtomic.js +40 -13
- package/dist/writeFileAtomic.js.map +1 -1
- package/package.json +14 -6
- package/scripts/mcp-stdio-shim.cjs +247 -87
- package/templates/CLAUDE.bridge.md +1 -1
- package/templates/recipes/dependency-bump.yaml +33 -0
- package/templates/recipes/incident-to-pr.yaml +187 -0
- package/templates/recipes/outcome-ingester.yaml +53 -0
- package/templates/recipes/release-notes.yaml +30 -0
- package/templates/recipes/triage-failing-tests-autofile.yaml +152 -0
- package/templates/recipes/triage-failing-tests.yaml +38 -0
- package/templates/workers/dependency-upkeep.worker.yaml +26 -0
- package/templates/workers/release-notes.worker.yaml +17 -0
- package/templates/workers/test-guardian.worker.yaml +24 -0
- package/deploy/README.md +0 -172
- package/deploy/bootstrap-new-vps.sh +0 -364
- package/deploy/bootstrap-vps.sh +0 -192
- package/deploy/claude-ide-bridge.service.template +0 -67
- package/deploy/claude-ide-bridge@.service +0 -31
- package/deploy/deploy-dashboard.sh +0 -198
- package/deploy/deploy-landing.sh +0 -136
- package/deploy/ecosystem.config.js.example +0 -36
- package/deploy/install-vps-service.sh +0 -240
- package/deploy/macos/README.md +0 -153
- package/deploy/macos/com.patchwork.bridge.plist.template +0 -54
- package/deploy/macos/com.patchwork.tunnel.plist.template +0 -76
- package/deploy/macos/install-mac-bridge.sh +0 -244
- package/deploy/macos/uninstall-mac-bridge.sh +0 -22
- package/deploy/nginx-claude-bridge.conf.template +0 -129
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { MAX_PERSIST_LINES, RecipeRunLog } from "../runLog.js";
|
|
5
|
+
import { classifyActionClass } from "./actionClass.js";
|
|
6
|
+
import { backtestWorker, formatBacktestReport } from "./backtest.js";
|
|
7
|
+
import { OutcomeStore, resolveOutcomeLogDir } from "./outcomeStore.js";
|
|
8
|
+
import { WorkerShadowObserver, } from "./shadowObserver.js";
|
|
9
|
+
import { buildShadowReport, formatShadowReport } from "./shadowReport.js";
|
|
10
|
+
import { loadWorkersFromDir } from "./workerLoader.js";
|
|
11
|
+
function readRuns(patchworkDir, recipeNames) {
|
|
12
|
+
try {
|
|
13
|
+
// Size the in-memory ring to the FULL disk retention (MAX_PERSIST_LINES), not
|
|
14
|
+
// the default 500. `query()` only ever scans the ring, so with the default
|
|
15
|
+
// cap a low-frequency worker's run is evicted once >500 unrelated runs land
|
|
16
|
+
// after it — even with a per-recipe filter (the filter is applied AFTER ring
|
|
17
|
+
// eviction). Matching the ring to the disk cap means worker evidence is
|
|
18
|
+
// bounded only by what the log actually retains, not by global run volume.
|
|
19
|
+
const log = new RecipeRunLog({
|
|
20
|
+
dir: patchworkDir,
|
|
21
|
+
memoryCap: MAX_PERSIST_LINES,
|
|
22
|
+
});
|
|
23
|
+
// Query FILTERED BY the worker recipes — NOT the global last-N window.
|
|
24
|
+
// `query({})` defaults to the 100 most-recent runs, so a low-frequency
|
|
25
|
+
// worker's evidence ages out behind unrelated high-frequency recipe traffic
|
|
26
|
+
// (this is exactly why the test-guardian dial read empty despite a real,
|
|
27
|
+
// correctly-executed run). Filtering means only same-recipe runs compete for
|
|
28
|
+
// the window. DEDUP the names first: two manifests can declare the same
|
|
29
|
+
// recipe, and an un-deduped flatMap would query it twice → ingest every run
|
|
30
|
+
// twice → double-count the dial's evidence (a dial-vs-gate divergence, since
|
|
31
|
+
// the live gate passes a single recipe name).
|
|
32
|
+
const names = recipeNames?.length
|
|
33
|
+
? Array.from(new Set(recipeNames))
|
|
34
|
+
: undefined;
|
|
35
|
+
// `query` clamps limit to 500, but it now scans the full-history ring, so
|
|
36
|
+
// this is the 500 most-recent runs OF THIS RECIPE — ample per-worker, and no
|
|
37
|
+
// longer evictable by unrelated traffic.
|
|
38
|
+
const rows = names
|
|
39
|
+
? names.flatMap((recipe) => log.query({ recipe, limit: 500 }))
|
|
40
|
+
: log.query({ limit: 500 });
|
|
41
|
+
return rows.map((r) => ({
|
|
42
|
+
recipeName: r.recipeName,
|
|
43
|
+
at: r.doneAt ?? r.startedAt ?? r.createdAt,
|
|
44
|
+
steps: (r.stepResults ?? []).map((s) => ({
|
|
45
|
+
tool: s.tool,
|
|
46
|
+
status: s.status,
|
|
47
|
+
haltReason: s.haltReason,
|
|
48
|
+
// Outcome attribution: carry the captured issue URL so ingestRun can
|
|
49
|
+
// look up the issue's disposition in the outcome store. Only present on
|
|
50
|
+
// github.create_issue steps (see yamlRunner.ts step output capture).
|
|
51
|
+
...(s.output !== undefined && typeof s.output === "object"
|
|
52
|
+
? { output: s.output }
|
|
53
|
+
: {}),
|
|
54
|
+
})),
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function readDecisions(ideDir) {
|
|
62
|
+
let files;
|
|
63
|
+
try {
|
|
64
|
+
files = readdirSync(ideDir).filter((f) => /^activity-.*\.jsonl$/.test(f));
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
const out = [];
|
|
70
|
+
for (const f of files) {
|
|
71
|
+
let text;
|
|
72
|
+
try {
|
|
73
|
+
text = readFileSync(path.join(ideDir, f), "utf-8");
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
for (const line of text.split("\n")) {
|
|
79
|
+
const t = line.trim();
|
|
80
|
+
// cheap pre-filter before the JSON.parse; an empty line never matches
|
|
81
|
+
if (!t.includes("approval_decision"))
|
|
82
|
+
continue;
|
|
83
|
+
let obj;
|
|
84
|
+
try {
|
|
85
|
+
obj = JSON.parse(t);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (obj.event !== "approval_decision")
|
|
91
|
+
continue;
|
|
92
|
+
const md = (obj.metadata ?? {});
|
|
93
|
+
const decision = md.decision === "allow"
|
|
94
|
+
? "allow"
|
|
95
|
+
: md.decision === "deny"
|
|
96
|
+
? "deny"
|
|
97
|
+
: null;
|
|
98
|
+
if (typeof md.toolName !== "string" || !decision)
|
|
99
|
+
continue;
|
|
100
|
+
out.push({
|
|
101
|
+
toolName: md.toolName,
|
|
102
|
+
decision,
|
|
103
|
+
at: typeof obj.timestamp === "string"
|
|
104
|
+
? Date.parse(obj.timestamp) || 0
|
|
105
|
+
: 0,
|
|
106
|
+
// Only present on worker-gate decisions (recipe runner path). Plain
|
|
107
|
+
// Claude-session MCP approvals have no recipeName; ingestDecision
|
|
108
|
+
// skips them so they don't inflate the ramp-vs-gate divergence count.
|
|
109
|
+
...(typeof md.recipeName === "string" && {
|
|
110
|
+
recipeName: md.recipeName,
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Structured shadow report — a read-only replay of the run + decision logs
|
|
119
|
+
* through the (worker × action-class) ramp. Backs both the CLI and the bridge
|
|
120
|
+
* `GET /workers/shadow` JSON endpoint. Pure aside from the log reads.
|
|
121
|
+
*/
|
|
122
|
+
export function getWorkerShadowData(opts = {}) {
|
|
123
|
+
const home = os.homedir();
|
|
124
|
+
const patchworkDir = opts.patchworkDir ?? path.join(home, ".patchwork");
|
|
125
|
+
const ideDir = opts.ideDir ?? path.join(home, ".claude", "ide");
|
|
126
|
+
const workersDir = opts.workersDir ?? path.join(patchworkDir, "workers");
|
|
127
|
+
const workers = loadWorkersFromDir(workersDir);
|
|
128
|
+
const runs = workers.length
|
|
129
|
+
? readRuns(patchworkDir, workers.map((w) => w.recipe).filter((r) => !!r))
|
|
130
|
+
: [];
|
|
131
|
+
const decisions = workers.length ? readDecisions(ideDir) : [];
|
|
132
|
+
return {
|
|
133
|
+
// `now` drives durable-outcome labelling (recent non-reversible successes
|
|
134
|
+
// are withheld until they survive the durability window). Real Date.now() in
|
|
135
|
+
// production; tests inject opts.now.
|
|
136
|
+
workers: buildShadowReport(workers, runs, decisions, undefined, {
|
|
137
|
+
now: opts.now ?? Date.now(),
|
|
138
|
+
// The outcome log honors PATCHWORK_HOME (matching every write path) even
|
|
139
|
+
// though runs.jsonl above is read from `patchworkDir` — the two files can
|
|
140
|
+
// live in different roots. Resolving them the same way here would break
|
|
141
|
+
// the confirm loop on a PATCHWORK_HOME box (write one file, read another).
|
|
142
|
+
outcomeStore: new OutcomeStore(resolveOutcomeLogDir(opts.patchworkDir)),
|
|
143
|
+
}),
|
|
144
|
+
runsScanned: runs.length,
|
|
145
|
+
decisionsScanned: decisions.length,
|
|
146
|
+
workersDir,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Load the worker that owns `recipeName` (recipe === body) plus its earned-level
|
|
151
|
+
* store, replayed from the same run log the dial uses. Returns null when no
|
|
152
|
+
* worker owns the recipe (the common case — non-worker recipes are unaffected).
|
|
153
|
+
*
|
|
154
|
+
* This is the LIVE-gate entry: `workerGate.decideWorkerAction(worker, tool,
|
|
155
|
+
* params, store)` reads the returned store. It replays the run log on each call
|
|
156
|
+
* (recipe executions are infrequent); a future optimisation could cache it.
|
|
157
|
+
*/
|
|
158
|
+
export function loadWorkerTrustForRecipe(recipeName, opts = {}) {
|
|
159
|
+
const home = os.homedir();
|
|
160
|
+
const patchworkDir = opts.patchworkDir ?? path.join(home, ".patchwork");
|
|
161
|
+
const workersDir = opts.workersDir ?? path.join(patchworkDir, "workers");
|
|
162
|
+
const workers = loadWorkersFromDir(workersDir);
|
|
163
|
+
if (!workers.length)
|
|
164
|
+
return null;
|
|
165
|
+
// Same durable-outcome labelling as the dial (one source of truth): the live
|
|
166
|
+
// gate must not count a recent non-reversible success that could still be
|
|
167
|
+
// reverted. Real Date.now() in production; tests inject opts.now.
|
|
168
|
+
const observer = new WorkerShadowObserver(workers, {
|
|
169
|
+
now: opts.now ?? Date.now(),
|
|
170
|
+
outcomeStore: new OutcomeStore(resolveOutcomeLogDir(opts.patchworkDir)),
|
|
171
|
+
});
|
|
172
|
+
const worker = observer.workerForRecipe(recipeName);
|
|
173
|
+
if (!worker)
|
|
174
|
+
return null;
|
|
175
|
+
// Replay in ASCENDING timestamp order (review #1027 M2). The graduation
|
|
176
|
+
// dwell/hysteresis logic is order-sensitive: ingesting newest-first leaves
|
|
177
|
+
// `lastChangeAt` pinned to the most recent run so `dwellOk` never holds and
|
|
178
|
+
// risky classes never promote — the earned-L4 path would be unreachable and
|
|
179
|
+
// the gate would floor every compensable/irreversible class to L0 forever.
|
|
180
|
+
// This mirrors buildShadowReport (the dial), so the gate and dial agree.
|
|
181
|
+
// `recipeName` === the owning worker's recipe (workerForRecipe matched on it),
|
|
182
|
+
// so filter the replay to just this recipe's runs.
|
|
183
|
+
const runs = readRuns(patchworkDir, [recipeName]).sort((a, b) => a.at - b.at);
|
|
184
|
+
for (const run of runs)
|
|
185
|
+
observer.ingestRun(run);
|
|
186
|
+
return { worker, store: observer.levelStore };
|
|
187
|
+
}
|
|
188
|
+
export function runWorkerShadowReport(opts = {}) {
|
|
189
|
+
const data = getWorkerShadowData(opts);
|
|
190
|
+
if (data.workers.length === 0) {
|
|
191
|
+
return `No worker manifests found in ${data.workersDir}.\nAdd *.worker.yaml there (e.g. copy templates/workers/) and re-run.\n`;
|
|
192
|
+
}
|
|
193
|
+
return `${formatShadowReport(data.workers)}\n(scanned ${data.runsScanned} recipe runs, ${data.decisionsScanned} gate decisions · read-only)\n`;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Backtest each installed worker over its historical run log and print the
|
|
197
|
+
* divergence-calibration report (false-allow / false-gate). Read-only — the
|
|
198
|
+
* cold-start "what would this worker have done across N real actions, and where
|
|
199
|
+
* would it have diverged" artifact. See backtest.ts.
|
|
200
|
+
*/
|
|
201
|
+
export function runWorkerBacktest(opts = {}) {
|
|
202
|
+
const home = os.homedir();
|
|
203
|
+
const patchworkDir = opts.patchworkDir ?? path.join(home, ".patchwork");
|
|
204
|
+
const workersDir = opts.workersDir ?? path.join(patchworkDir, "workers");
|
|
205
|
+
const workers = loadWorkersFromDir(workersDir);
|
|
206
|
+
if (!workers.length) {
|
|
207
|
+
return `No worker manifests found in ${workersDir}.\nAdd *.worker.yaml there (e.g. copy templates/workers/) and re-run.\n`;
|
|
208
|
+
}
|
|
209
|
+
const lines = [
|
|
210
|
+
"Worker trust BACKTEST — divergence calibration (read-only)",
|
|
211
|
+
" false-allow = ramp would auto-run a BAD action (over-trust, the risk)",
|
|
212
|
+
" false-gate = ramp would gate a GOOD action (over-caution, the cost)",
|
|
213
|
+
"",
|
|
214
|
+
];
|
|
215
|
+
const outcomeStore = new OutcomeStore(resolveOutcomeLogDir(opts.patchworkDir));
|
|
216
|
+
for (const w of workers) {
|
|
217
|
+
if (!w.recipe)
|
|
218
|
+
continue;
|
|
219
|
+
const runs = readRuns(patchworkDir, [w.recipe]);
|
|
220
|
+
lines.push(formatBacktestReport(backtestWorker(w, runs, { outcomeStore })));
|
|
221
|
+
}
|
|
222
|
+
return lines.join("\n");
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* The CONFIRM QUEUE — every non-reversible filing (a URL a worker captured) that
|
|
226
|
+
* has NO operator disposition yet (`unknown` / no record). These are exactly the
|
|
227
|
+
* filings whose trust is WITHHELD until a human confirms or rejects them — the
|
|
228
|
+
* queue `patchwork outcomes confirm|reject` exists to drain, and the moat KPI
|
|
229
|
+
* (evidence latency) is the age of this queue. Read-only. Deduped by URL
|
|
230
|
+
* (most-recent filing wins), newest first. Confirmed/junk filings are excluded
|
|
231
|
+
* (already actioned); reversible actions are excluded (they never need
|
|
232
|
+
* confirmation — they earn trust on their own). In practice today only issue
|
|
233
|
+
* filings (`github.create_issue`) carry a captured URL.
|
|
234
|
+
*/
|
|
235
|
+
export function computePendingConfirmations(opts = {}) {
|
|
236
|
+
const home = os.homedir();
|
|
237
|
+
const patchworkDir = opts.patchworkDir ?? path.join(home, ".patchwork");
|
|
238
|
+
const workersDir = opts.workersDir ?? path.join(patchworkDir, "workers");
|
|
239
|
+
// Same PATCHWORK_HOME-aware resolver the write path uses (see slice #3), so
|
|
240
|
+
// the queue reflects exactly what a confirm would write.
|
|
241
|
+
const store = new OutcomeStore(resolveOutcomeLogDir(opts.patchworkDir));
|
|
242
|
+
const workers = loadWorkersFromDir(workersDir);
|
|
243
|
+
// Attribute each run to the FIRST worker declaring its recipe (mirrors the
|
|
244
|
+
// dial's first-match attribution), and read the run log ONCE over the union
|
|
245
|
+
// of recipe names — readRuns already dedups the names — rather than
|
|
246
|
+
// re-parsing the whole log per worker.
|
|
247
|
+
const workerForRecipe = new Map();
|
|
248
|
+
for (const w of workers) {
|
|
249
|
+
if (w.recipe && !workerForRecipe.has(w.recipe)) {
|
|
250
|
+
workerForRecipe.set(w.recipe, w);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const recipeNames = Array.from(workerForRecipe.keys());
|
|
254
|
+
if (recipeNames.length === 0)
|
|
255
|
+
return []; // no workers → nothing to attribute
|
|
256
|
+
const byUrl = new Map();
|
|
257
|
+
for (const run of readRuns(patchworkDir, recipeNames)) {
|
|
258
|
+
const w = workerForRecipe.get(run.recipeName);
|
|
259
|
+
if (!w)
|
|
260
|
+
continue;
|
|
261
|
+
for (const step of run.steps) {
|
|
262
|
+
if (!step.tool || step.status !== "ok")
|
|
263
|
+
continue;
|
|
264
|
+
const ac = classifyActionClass(step.tool);
|
|
265
|
+
if (ac.reversibility === "reversible")
|
|
266
|
+
continue; // never needs confirming
|
|
267
|
+
const out = step.output;
|
|
268
|
+
const url = out && typeof out.url === "string" ? out.url : null;
|
|
269
|
+
if (!url)
|
|
270
|
+
continue;
|
|
271
|
+
const title = out && typeof out.title === "string" && out.title.trim()
|
|
272
|
+
? out.title
|
|
273
|
+
: undefined;
|
|
274
|
+
const disp = store.getDisposition(url);
|
|
275
|
+
if (disp === "confirmed" || disp === "junk")
|
|
276
|
+
continue; // already actioned
|
|
277
|
+
// unknown / no record → pending. Dedup by URL, keep the newest filing.
|
|
278
|
+
const prev = byUrl.get(url);
|
|
279
|
+
if (!prev || run.at > prev.filedAt) {
|
|
280
|
+
byUrl.set(url, {
|
|
281
|
+
issueUrl: url,
|
|
282
|
+
recipeName: run.recipeName,
|
|
283
|
+
workerId: w.id,
|
|
284
|
+
workerName: w.name,
|
|
285
|
+
filedAt: run.at,
|
|
286
|
+
classKey: ac.key,
|
|
287
|
+
title,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return Array.from(byUrl.values()).sort((a, b) => b.filedAt - a.filedAt);
|
|
293
|
+
}
|
|
294
|
+
/** Human-readable confirm queue for `patchwork outcomes pending`. */
|
|
295
|
+
export function formatPendingConfirmations(pending, now = Date.now()) {
|
|
296
|
+
if (pending.length === 0) {
|
|
297
|
+
return "No filings awaiting confirmation — every worker filing has an operator disposition.\n";
|
|
298
|
+
}
|
|
299
|
+
const rel = (at) => {
|
|
300
|
+
const ms = Math.max(0, now - at);
|
|
301
|
+
const h = Math.floor(ms / 3_600_000);
|
|
302
|
+
if (h < 1)
|
|
303
|
+
return "just now";
|
|
304
|
+
if (h < 24)
|
|
305
|
+
return `${h}h ago`;
|
|
306
|
+
return `${Math.floor(h / 24)}d ago`;
|
|
307
|
+
};
|
|
308
|
+
const lines = [
|
|
309
|
+
`${pending.length} filing(s) awaiting your confirmation (the confirm queue):`,
|
|
310
|
+
"",
|
|
311
|
+
];
|
|
312
|
+
for (const p of pending) {
|
|
313
|
+
lines.push(p.title ? ` "${p.title}"` : ` ${p.issueUrl}`);
|
|
314
|
+
if (p.title)
|
|
315
|
+
lines.push(` ${p.issueUrl}`);
|
|
316
|
+
lines.push(` filed by ${p.workerName} (${p.recipeName}) · ${p.classKey} · ${rel(p.filedAt)}`);
|
|
317
|
+
lines.push(` confirm: patchwork outcomes confirm ${p.issueUrl} --recipe ${p.recipeName} --class ${p.classKey}`);
|
|
318
|
+
lines.push(` reject: patchwork outcomes reject ${p.issueUrl} --recipe ${p.recipeName} --class ${p.classKey}`);
|
|
319
|
+
lines.push("");
|
|
320
|
+
}
|
|
321
|
+
return lines.join("\n");
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=runWorkerShadow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runWorkerShadow.js","sourceRoot":"","sources":["../../src/workers/runWorkerShadow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { TrustLevel } from "./trustLevel.js";
|
|
2
|
+
import { type WorkerManifest } from "./worker.js";
|
|
3
|
+
import type { WorkerLevelStore } from "./workerLevelStore.js";
|
|
4
|
+
/**
|
|
5
|
+
* What the ramp WOULD decide for a worker's action — a PURE recommendation.
|
|
6
|
+
*
|
|
7
|
+
* v0 is shadow-only: this is NOT wired into the live approval gate
|
|
8
|
+
* (`evaluateInProcessGate`). Flipping the gate to obey the ramp is a deliberate,
|
|
9
|
+
* flag-gated phase-2 step, taken only after shadow data shows the ramp's
|
|
10
|
+
* decisions track reality. Until then this exists to log "ramp would bypass /
|
|
11
|
+
* gate did queue" and to drive the dial.
|
|
12
|
+
*
|
|
13
|
+
* The effective level drives two thresholds that mirror the live gate:
|
|
14
|
+
* compensable at L2+ → bypass; irreversible at L4+ → bypass; else → queue.
|
|
15
|
+
* The full earned level (0–4) is reported for the dial. The effective level is
|
|
16
|
+
* `min(earned, autonomyCeiling)`, floored to 0 for actions outside the worker's
|
|
17
|
+
* domain — a worker has no standing trust on things it doesn't own.
|
|
18
|
+
*/
|
|
19
|
+
export interface ShadowDecision {
|
|
20
|
+
decision: "queue" | "bypass";
|
|
21
|
+
classKey: string;
|
|
22
|
+
owned: boolean;
|
|
23
|
+
/** Trust the worker has actually earned on this class (drives the dial). */
|
|
24
|
+
earnedLevel: TrustLevel;
|
|
25
|
+
autonomyCeiling: TrustLevel;
|
|
26
|
+
/** What the gate would operate at: min(earned, ceiling), 0 if not owned. */
|
|
27
|
+
effectiveLevel: TrustLevel;
|
|
28
|
+
reason: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function recommend(worker: WorkerManifest, toolName: string, params: Record<string, unknown> | undefined, store: WorkerLevelStore): ShadowDecision;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { classifyActionClass } from "./actionClass.js";
|
|
2
|
+
import { ownsAction } from "./worker.js";
|
|
3
|
+
const COMPENSABLE_AUTONOMY_LEVEL = 2;
|
|
4
|
+
const AUTONOMOUS_LEVEL = 4;
|
|
5
|
+
export function recommend(worker, toolName, params, store) {
|
|
6
|
+
const ac = classifyActionClass(toolName, params);
|
|
7
|
+
const owned = ownsAction(worker, ac);
|
|
8
|
+
// Reversible actions always bypass — no trust threshold applies. Short-
|
|
9
|
+
// circuiting here prevents false divergence-log noise (the dial would
|
|
10
|
+
// otherwise compare against L4 and always report a "miss" for reads).
|
|
11
|
+
if (ac.reversibility === "reversible") {
|
|
12
|
+
const earnedLevel = (store.getState(worker.id, ac.key)?.level ??
|
|
13
|
+
0);
|
|
14
|
+
return {
|
|
15
|
+
decision: "bypass",
|
|
16
|
+
classKey: ac.key,
|
|
17
|
+
owned,
|
|
18
|
+
earnedLevel,
|
|
19
|
+
autonomyCeiling: worker.autonomyCeiling,
|
|
20
|
+
effectiveLevel: owned ? earnedLevel : 0,
|
|
21
|
+
reason: "reversible — flows un-gated regardless of earned level",
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const earnedLevel = (store.getState(worker.id, ac.key)?.level ??
|
|
25
|
+
0);
|
|
26
|
+
let effectiveLevel = owned ? earnedLevel : 0;
|
|
27
|
+
if (effectiveLevel > worker.autonomyCeiling)
|
|
28
|
+
effectiveLevel = worker.autonomyCeiling;
|
|
29
|
+
const decision = ac.reversibility === "compensable"
|
|
30
|
+
? effectiveLevel >= COMPENSABLE_AUTONOMY_LEVEL
|
|
31
|
+
? "bypass"
|
|
32
|
+
: "queue"
|
|
33
|
+
: effectiveLevel >= AUTONOMOUS_LEVEL
|
|
34
|
+
? "bypass"
|
|
35
|
+
: "queue";
|
|
36
|
+
const threshold = ac.reversibility === "compensable"
|
|
37
|
+
? COMPENSABLE_AUTONOMY_LEVEL
|
|
38
|
+
: AUTONOMOUS_LEVEL;
|
|
39
|
+
let reason;
|
|
40
|
+
if (!owned)
|
|
41
|
+
reason = "outside-worker-domain";
|
|
42
|
+
else if (worker.autonomyCeiling < threshold)
|
|
43
|
+
reason = `capped-by-autonomy-ceiling (L${worker.autonomyCeiling} < L${threshold}, earned L${earnedLevel})`;
|
|
44
|
+
else if (decision === "bypass")
|
|
45
|
+
reason = `autonomous (earned L${effectiveLevel}, threshold L${threshold})`;
|
|
46
|
+
else
|
|
47
|
+
reason = `below-autonomy (effective L${effectiveLevel} < L${threshold})`;
|
|
48
|
+
return {
|
|
49
|
+
decision,
|
|
50
|
+
classKey: ac.key,
|
|
51
|
+
owned,
|
|
52
|
+
earnedLevel,
|
|
53
|
+
autonomyCeiling: worker.autonomyCeiling,
|
|
54
|
+
effectiveLevel,
|
|
55
|
+
reason,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=shadowGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadowGate.js","sourceRoot":"","sources":["../../src/workers/shadowGate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAuB,MAAM,aAAa,CAAC;AA+B9D,MAAM,0BAA0B,GAAG,CAAC,CAAC;AACrC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAE3B,MAAM,UAAU,SAAS,CACvB,MAAsB,EACtB,QAAgB,EAChB,MAA2C,EAC3C,KAAuB;IAEvB,MAAM,EAAE,GAAG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAErC,wEAAwE;IACxE,sEAAsE;IACtE,sEAAsE;IACtE,IAAI,EAAE,CAAC,aAAa,KAAK,YAAY,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK;YAC3D,CAAC,CAAe,CAAC;QACnB,OAAO;YACL,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,EAAE,CAAC,GAAG;YAChB,KAAK;YACL,WAAW;YACX,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAE,CAAgB;YACvD,MAAM,EAAE,wDAAwD;SACjE,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK;QAC3D,CAAC,CAAe,CAAC;IAEnB,IAAI,cAAc,GAAe,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,IAAI,cAAc,GAAG,MAAM,CAAC,eAAe;QACzC,cAAc,GAAG,MAAM,CAAC,eAAe,CAAC;IAE1C,MAAM,QAAQ,GACZ,EAAE,CAAC,aAAa,KAAK,aAAa;QAChC,CAAC,CAAC,cAAc,IAAI,0BAA0B;YAC5C,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,OAAO;QACX,CAAC,CAAC,cAAc,IAAI,gBAAgB;YAClC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,OAAO,CAAC;IAEhB,MAAM,SAAS,GACb,EAAE,CAAC,aAAa,KAAK,aAAa;QAChC,CAAC,CAAC,0BAA0B;QAC5B,CAAC,CAAC,gBAAgB,CAAC;IACvB,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC,KAAK;QAAE,MAAM,GAAG,uBAAuB,CAAC;SACxC,IAAI,MAAM,CAAC,eAAe,GAAG,SAAS;QACzC,MAAM,GAAG,gCAAgC,MAAM,CAAC,eAAe,OAAO,SAAS,aAAa,WAAW,GAAG,CAAC;SACxG,IAAI,QAAQ,KAAK,QAAQ;QAC5B,MAAM,GAAG,uBAAuB,cAAc,gBAAgB,SAAS,GAAG,CAAC;;QACxE,MAAM,GAAG,8BAA8B,cAAc,OAAO,SAAS,GAAG,CAAC;IAE9E,OAAO;QACL,QAAQ;QACR,QAAQ,EAAE,EAAE,CAAC,GAAG;QAChB,KAAK;QACL,WAAW;QACX,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,cAAc;QACd,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { type Reversibility } from "./actionClass.js";
|
|
2
|
+
import { type GraduationConfig } from "./graduation.js";
|
|
3
|
+
import type { OutcomeStore } from "./outcomeStore.js";
|
|
4
|
+
import { type WorkerManifest } from "./worker.js";
|
|
5
|
+
import { type AuditEvent, type BoardRow, WorkerLevelStore } from "./workerLevelStore.js";
|
|
6
|
+
/**
|
|
7
|
+
* Read-only shadow logger. Consumes signals the bridge ALREADY persists —
|
|
8
|
+
* RecipeRunLog outcomes (the dial's evidence) and ActivityLog approval
|
|
9
|
+
* decisions (the live gate's actual calls) — and maintains the trust dial +
|
|
10
|
+
* a "what the ramp WOULD have decided vs what the gate DID" comparison. It
|
|
11
|
+
* never touches the live gate: the gate's own decision log IS the input, so
|
|
12
|
+
* this observes the live path with zero hot-path risk. (worker-ramp-v0, shadow)
|
|
13
|
+
*/
|
|
14
|
+
/** A recipe run, reduced to what the dial needs (maps from RecipeRun). */
|
|
15
|
+
export interface RunRecord {
|
|
16
|
+
recipeName: string;
|
|
17
|
+
/** epoch ms */
|
|
18
|
+
at: number;
|
|
19
|
+
steps: Array<{
|
|
20
|
+
tool?: string;
|
|
21
|
+
status: "ok" | "skipped" | "error";
|
|
22
|
+
/** Persisted halt reason — used to tell a worker failure apart from a
|
|
23
|
+
* human approval decision (the latter is not trust evidence; see L2). */
|
|
24
|
+
haltReason?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Captured tool output for outcome attribution. Only populated for
|
|
27
|
+
* github.create_issue steps (contains `{url, issueNumber}`). Used by
|
|
28
|
+
* ingestRun to look up the issue's eventual disposition in the outcome
|
|
29
|
+
* store so junk filings flip to good:false rather than counting as earned
|
|
30
|
+
* trust. See outcomeStore.ts.
|
|
31
|
+
*/
|
|
32
|
+
output?: Record<string, unknown>;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
/** A live gate decision (maps from an ActivityLog approval_decision row). */
|
|
36
|
+
export interface DecisionRecord {
|
|
37
|
+
toolName: string;
|
|
38
|
+
/** the gate's actual verdict */
|
|
39
|
+
decision: "allow" | "deny";
|
|
40
|
+
at: number;
|
|
41
|
+
params?: Record<string, unknown>;
|
|
42
|
+
/** Present only on worker-gate decisions (recipe runner path). Absent on
|
|
43
|
+
* Claude-session MCP tool approvals — the shadow only counts worker-gate
|
|
44
|
+
* decisions so mixing in session approvals won't inflate divergences. */
|
|
45
|
+
recipeName?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface Divergence {
|
|
48
|
+
classKey: string;
|
|
49
|
+
toolName: string;
|
|
50
|
+
ramp: "queue" | "bypass";
|
|
51
|
+
gate: "allow" | "deny";
|
|
52
|
+
at: number;
|
|
53
|
+
note: string;
|
|
54
|
+
}
|
|
55
|
+
export interface WorkerShadowReport {
|
|
56
|
+
workerId: string;
|
|
57
|
+
name: string;
|
|
58
|
+
autonomyCeiling: number;
|
|
59
|
+
/** Dial rows. `owned: false` = the worker performed this class but does not
|
|
60
|
+
* own it, so the live gate floors it to L0 regardless of accrued evidence. */
|
|
61
|
+
board: Array<BoardRow & {
|
|
62
|
+
owned: boolean;
|
|
63
|
+
}>;
|
|
64
|
+
events: AuditEvent[];
|
|
65
|
+
/** ramp-vs-gate comparison over attributable decisions */
|
|
66
|
+
compared: number;
|
|
67
|
+
agreed: number;
|
|
68
|
+
divergences: Divergence[];
|
|
69
|
+
}
|
|
70
|
+
/** Default durability window — a non-reversible success must survive this long
|
|
71
|
+
* before it counts as earned trust. 24h is long enough to catch a revert /
|
|
72
|
+
* close-as-junk / rollback, short enough that a genuinely-good action graduates
|
|
73
|
+
* within a day. */
|
|
74
|
+
export declare const DEFAULT_DURABILITY_WINDOW_MS: number;
|
|
75
|
+
/**
|
|
76
|
+
* Durable-outcome label. `good = step.status:ok` is an OPTIMISTIC proxy: a PR
|
|
77
|
+
* that merged, an issue that filed — but a junk issue closed seconds later, or a
|
|
78
|
+
* commit reverted within the hour, "succeeded" at the moment yet is not earned
|
|
79
|
+
* trust. So a SUCCESS on a non-reversible (compensable/irreversible) action is
|
|
80
|
+
* "durable" — i.e. counts as evidence — only once it has survived the durability
|
|
81
|
+
* window. Reversible successes (undoable / re-runnable: reads, ledgered writes,
|
|
82
|
+
* local commits, CI) are always durable. Failures are unaffected (a failure is
|
|
83
|
+
* durable evidence of failure regardless of age).
|
|
84
|
+
*
|
|
85
|
+
* This only ever WITHHOLDS recent risky successes (reduces evidence → lower
|
|
86
|
+
* trust → more gating), so it never widens autonomy. See
|
|
87
|
+
* docs/worker-autonomy-policy-gate.md §3d.
|
|
88
|
+
*/
|
|
89
|
+
export declare function isDurableSuccess(reversibility: Reversibility, runAt: number, now: number, windowMs: number): boolean;
|
|
90
|
+
/** A single step reduced to what the outcome fold needs. */
|
|
91
|
+
type FoldStep = Pick<RunRecord["steps"][number], "tool" | "status" | "output">;
|
|
92
|
+
/**
|
|
93
|
+
* The durable-outcome fold decision for one step — the SINGLE source of truth
|
|
94
|
+
* shared by the live/shadow dial (`WorkerShadowObserver.ingestRun`) and the
|
|
95
|
+
* cold-start backtest (`backtestWorker`), so the two can never drift on how an
|
|
96
|
+
* outcome is labelled. Returns either "withhold" (not evidence — a pending or
|
|
97
|
+
* unknown-disposition risky success) or "count as good/bad".
|
|
98
|
+
*
|
|
99
|
+
* Assumes the caller has already skipped no-tool / skipped / approval-rejected
|
|
100
|
+
* steps (those are non-evidence for reasons the caller owns). Semantics (the
|
|
101
|
+
* junk check runs BEFORE the durability window — a human rejection is durable
|
|
102
|
+
* evidence of failure the moment it lands, so it demotes instantly, like any
|
|
103
|
+
* outright failure; only confirmed/unknown successes wait out the window):
|
|
104
|
+
* - failure (status ≠ ok) → count, good:false (durable evidence of failure)
|
|
105
|
+
* - success, no `now` → count, good:true (back-compat status-only)
|
|
106
|
+
* - success, non-reversible, junk (any age) → count, good:false (human-rejected → demotes now)
|
|
107
|
+
* - success, non-reversible, pre-window → WITHHOLD (provisional; not yet durable)
|
|
108
|
+
* - success, non-reversible, unknown/null → WITHHOLD (unactioned ≠ correct; trust-by-neglect fix)
|
|
109
|
+
* - success, otherwise (reversible / confirmed / no url / no store) → count, good:true
|
|
110
|
+
*/
|
|
111
|
+
export type FoldDecision = {
|
|
112
|
+
fold: false;
|
|
113
|
+
} | {
|
|
114
|
+
fold: true;
|
|
115
|
+
good: boolean;
|
|
116
|
+
};
|
|
117
|
+
export declare function foldOutcome(step: FoldStep, runAt: number, opts: {
|
|
118
|
+
now?: number;
|
|
119
|
+
windowMs: number;
|
|
120
|
+
outcomeStore?: OutcomeStore;
|
|
121
|
+
}): FoldDecision;
|
|
122
|
+
export declare class WorkerShadowObserver {
|
|
123
|
+
private readonly store;
|
|
124
|
+
private readonly cfg;
|
|
125
|
+
private readonly workers;
|
|
126
|
+
private readonly compare;
|
|
127
|
+
/** Wall-clock supplied by the I/O entry (the observer stays pure — no
|
|
128
|
+
* Date.now). When set, durable-outcome labelling is active; when undefined,
|
|
129
|
+
* the prior status-only behaviour is preserved (back-compat for pure tests). */
|
|
130
|
+
private readonly now?;
|
|
131
|
+
private readonly durabilityWindowMs;
|
|
132
|
+
/** Optional outcome store — when present, junk issues flip good:false past
|
|
133
|
+
* the durability window instead of counting as earned trust. */
|
|
134
|
+
private readonly outcomeStore?;
|
|
135
|
+
constructor(workers: WorkerManifest[], opts?: {
|
|
136
|
+
store?: WorkerLevelStore;
|
|
137
|
+
cfg?: GraduationConfig;
|
|
138
|
+
now?: number;
|
|
139
|
+
durabilityWindowMs?: number;
|
|
140
|
+
outcomeStore?: OutcomeStore;
|
|
141
|
+
});
|
|
142
|
+
/**
|
|
143
|
+
* The populated level store. Exposed so the LIVE worker-autonomy gate
|
|
144
|
+
* (`workerGate.decideWorkerAction`) can read the same earned levels this
|
|
145
|
+
* observer derives from the run log — one source of truth for the dial and
|
|
146
|
+
* the gate. Read-only intent; callers must not mutate.
|
|
147
|
+
*/
|
|
148
|
+
get levelStore(): WorkerLevelStore;
|
|
149
|
+
/** The worker whose recipe body is `recipeName`, if any. */
|
|
150
|
+
workerForRecipe(recipeName: string): WorkerManifest | undefined;
|
|
151
|
+
/** Attribute a tool call to its SOLE owning worker (ambiguous → skip). */
|
|
152
|
+
private workerForAction;
|
|
153
|
+
/** Feed a recipe run's step outcomes into the owning worker's dial. */
|
|
154
|
+
ingestRun(run: RunRecord): void;
|
|
155
|
+
/** Compare what the ramp WOULD recommend (given the dial as of now) against
|
|
156
|
+
* the gate's actual decision. Read-only — records agreement + divergences.
|
|
157
|
+
*
|
|
158
|
+
* Only worker-gate decisions (those with a recipeName) are counted. Plain
|
|
159
|
+
* Claude-session MCP tool approvals share the same ActivityLog event type
|
|
160
|
+
* but have no recipeName — including them would inflate divergences with
|
|
161
|
+
* calls the worker gate never saw. */
|
|
162
|
+
ingestDecision(d: DecisionRecord): void;
|
|
163
|
+
report(): WorkerShadowReport[];
|
|
164
|
+
}
|
|
165
|
+
export {};
|