@wardby/cli 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +33 -0
- package/README.md +25 -14
- package/dist/claude-coding-worker/context.d.ts +22 -0
- package/dist/claude-coding-worker/context.js +92 -0
- package/dist/claude-coding-worker/driver.d.ts +7 -1
- package/dist/claude-coding-worker/driver.js +38 -5
- package/dist/claude-coding-worker/sdk.js +13 -4
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +5 -2
- package/dist/cli-native-mode.d.ts +9 -0
- package/dist/cli-native-mode.js +20 -0
- package/dist/cli.d.ts +3 -1
- package/dist/cli.js +141 -5
- package/dist/coding/claude-context.d.ts +45 -0
- package/dist/coding/claude-context.js +434 -0
- package/dist/coding/profile.d.ts +12 -0
- package/dist/coding/profile.js +6 -0
- package/dist/coding/protocol.d.ts +104 -0
- package/dist/coding/protocol.js +87 -3
- package/dist/coding-worker/artifact.d.ts +8 -0
- package/dist/coding-worker/artifact.js +2 -2
- package/dist/coding-worker/driver.js +2 -0
- package/dist/coding-worker/sdk.d.ts +6 -0
- package/dist/coding-worker/sdk.js +1 -0
- package/dist/coding-worker/skills.d.ts +23 -0
- package/dist/coding-worker/skills.js +117 -0
- package/dist/coding-worker/types.d.ts +2 -0
- package/dist/config/github-allowed-accounts.d.ts +15 -0
- package/dist/config/github-allowed-accounts.js +36 -0
- package/dist/config/low-power.d.ts +12 -0
- package/dist/config/low-power.js +18 -0
- package/dist/config/mobile.d.ts +12 -0
- package/dist/config/mobile.js +18 -0
- package/dist/config/providers.d.ts +53 -0
- package/dist/config/providers.js +92 -6
- package/dist/core/db.d.ts +16 -6
- package/dist/core/db.js +12 -10
- package/dist/core/dispatch.d.ts +11 -0
- package/dist/core/dispatch.js +36 -1
- package/dist/core/engine-native.js +9 -5
- package/dist/core/host-events.d.ts +49 -3
- package/dist/core/host-events.js +289 -15
- package/dist/core/issue-bridge.js +42 -2
- package/dist/core/issue-events.js +12 -1
- package/dist/core/issue-status.js +14 -3
- package/dist/core/merge-order-check.d.ts +129 -0
- package/dist/core/merge-order-check.js +336 -0
- package/dist/core/notification-dispatcher.d.ts +70 -0
- package/dist/core/notification-dispatcher.js +368 -0
- package/dist/core/notification-templates.d.ts +25 -0
- package/dist/core/notification-templates.js +105 -0
- package/dist/core/notifications.d.ts +10 -0
- package/dist/core/notifications.js +38 -0
- package/dist/core/pg-auth.d.ts +22 -0
- package/dist/core/pg-auth.js +152 -0
- package/dist/core/power-composition.d.ts +16 -0
- package/dist/core/power-composition.js +37 -0
- package/dist/core/power-idle.d.ts +14 -0
- package/dist/core/power-idle.js +30 -0
- package/dist/core/power.d.ts +71 -0
- package/dist/core/power.js +202 -0
- package/dist/core/reconciler.d.ts +4 -2
- package/dist/core/reconciler.js +29 -5
- package/dist/core/related-pull-requests.d.ts +48 -4
- package/dist/core/related-pull-requests.js +113 -11
- package/dist/core/repo-access.d.ts +15 -0
- package/dist/core/repo-access.js +66 -0
- package/dist/core/review-fix.d.ts +37 -0
- package/dist/core/review-fix.js +207 -6
- package/dist/core/review-host-tools.d.ts +20 -0
- package/dist/core/review-host-tools.js +58 -2
- package/dist/core/runner.d.ts +336 -3
- package/dist/core/runner.js +894 -317
- package/dist/core/secret-broker-config.d.ts +103 -0
- package/dist/core/secret-broker-config.js +112 -0
- package/dist/core/secrets.d.ts +39 -4
- package/dist/core/secrets.js +148 -40
- package/dist/core/workflow-event-recorder.d.ts +14 -0
- package/dist/core/workflow-event-recorder.js +120 -0
- package/dist/core/workflow-events.d.ts +82 -0
- package/dist/core/workflow-events.js +44 -0
- package/dist/core/workflow-run-events.d.ts +16 -0
- package/dist/core/workflow-run-events.js +40 -0
- package/dist/generated/prisma/browser.d.ts +58 -0
- package/dist/generated/prisma/client.d.ts +58 -0
- package/dist/generated/prisma/commonInputTypes.d.ts +150 -0
- package/dist/generated/prisma/enums.d.ts +27 -0
- package/dist/generated/prisma/enums.js +23 -0
- package/dist/generated/prisma/internal/class.d.ts +88 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +772 -1
- package/dist/generated/prisma/internal/prismaNamespace.js +135 -4
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +139 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +135 -4
- package/dist/generated/prisma/models/Agent.d.ts +360 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +73 -1
- package/dist/generated/prisma/models/CodingRun.d.ts +205 -1
- package/dist/generated/prisma/models/DeferredReview.d.ts +78 -1
- package/dist/generated/prisma/models/NativeGatewayCall.d.ts +1675 -0
- package/dist/generated/prisma/models/NativeGatewayCall.js +1 -0
- package/dist/generated/prisma/models/NativeGatewaySession.d.ts +1517 -0
- package/dist/generated/prisma/models/NativeGatewaySession.js +1 -0
- package/dist/generated/prisma/models/NativeWarmWorker.d.ts +1296 -0
- package/dist/generated/prisma/models/NativeWarmWorker.js +1 -0
- package/dist/generated/prisma/models/NotificationChannel.d.ts +1543 -0
- package/dist/generated/prisma/models/NotificationChannel.js +1 -0
- package/dist/generated/prisma/models/NotificationDelivery.d.ts +1502 -0
- package/dist/generated/prisma/models/NotificationDelivery.js +1 -0
- package/dist/generated/prisma/models/NotificationThread.d.ts +1090 -0
- package/dist/generated/prisma/models/NotificationThread.js +1 -0
- package/dist/generated/prisma/models/Run.d.ts +826 -1
- package/dist/generated/prisma/models/RunHostCheck.d.ts +36 -1
- package/dist/generated/prisma/models/Secret.d.ts +37 -1
- package/dist/generated/prisma/models/SecretBrokerChange.d.ts +1101 -0
- package/dist/generated/prisma/models/SecretBrokerChange.js +1 -0
- package/dist/generated/prisma/models/WorkflowEvent.d.ts +1422 -0
- package/dist/generated/prisma/models/WorkflowEvent.js +1 -0
- package/dist/generated/prisma/models.d.ts +8 -0
- package/dist/help/build.js +4 -2
- package/dist/help/catalog.d.ts +1 -1
- package/dist/help/catalog.js +31 -6
- package/dist/help-index.json +1363 -176
- package/dist/import/create.js +17 -0
- package/dist/import/neutral-schema.d.ts +6 -2
- package/dist/import/neutral-schema.js +2 -0
- package/dist/mcp/auth/access.d.ts +1 -0
- package/dist/mcp/auth/repo-authorization.js +14 -0
- package/dist/mcp/auth/resource-server.d.ts +2 -1
- package/dist/mcp/auth/resource-server.js +7 -2
- package/dist/mcp/auth/self-hosted/browser.d.ts +1 -1
- package/dist/mcp/auth/self-hosted/browser.js +19 -6
- package/dist/mcp/context.d.ts +6 -0
- package/dist/mcp/host-events/github-ingress.d.ts +23 -1
- package/dist/mcp/host-events/github-ingress.js +68 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.js +59 -10
- package/dist/mcp/tools/agents.js +82 -11
- package/dist/mcp/tools/notification-channels.d.ts +2 -0
- package/dist/mcp/tools/notification-channels.js +293 -0
- package/dist/mcp/tools/power.d.ts +2 -0
- package/dist/mcp/tools/power.js +77 -0
- package/dist/mcp/tools/runs.d.ts +0 -6
- package/dist/mcp/tools/runs.js +7 -2
- package/dist/mcp/tools/secret-broker-compat.d.ts +12 -0
- package/dist/mcp/tools/secret-broker-compat.js +23 -0
- package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -2
- package/dist/mcp/tools/secret-elicitation-form.js +200 -10
- package/dist/mcp/tools/secret-elicitation-server.js +8 -1
- package/dist/mcp/tools/secret-elicitation.d.ts +38 -3
- package/dist/mcp/tools/secret-elicitation.js +110 -12
- package/dist/mcp/tools/secrets.js +184 -7
- package/dist/mcp/tools/tools.d.ts +1 -1
- package/dist/mcp/tools/tools.js +22 -2
- package/dist/native-worker/composition.d.ts +23 -0
- package/dist/native-worker/composition.js +77 -0
- package/dist/native-worker/docker-isolation.d.ts +65 -0
- package/dist/native-worker/docker-isolation.js +183 -0
- package/dist/native-worker/docker-launcher.d.ts +74 -0
- package/dist/native-worker/docker-launcher.js +237 -0
- package/dist/native-worker/gateway-server.d.ts +39 -0
- package/dist/native-worker/gateway-server.js +315 -0
- package/dist/native-worker/gateway.d.ts +44 -0
- package/dist/native-worker/gateway.js +197 -0
- package/dist/native-worker/http-server.d.ts +22 -0
- package/dist/native-worker/http-server.js +109 -0
- package/dist/native-worker/http-transport.d.ts +17 -0
- package/dist/native-worker/http-transport.js +88 -0
- package/dist/native-worker/kubernetes-isolation.d.ts +90 -0
- package/dist/native-worker/kubernetes-isolation.js +218 -0
- package/dist/native-worker/kubernetes-launcher.d.ts +102 -0
- package/dist/native-worker/kubernetes-launcher.js +335 -0
- package/dist/native-worker/launch.d.ts +45 -0
- package/dist/native-worker/launch.js +44 -0
- package/dist/native-worker/ledger.d.ts +109 -0
- package/dist/native-worker/ledger.js +192 -0
- package/dist/native-worker/loopback.d.ts +12 -0
- package/dist/native-worker/loopback.js +49 -0
- package/dist/native-worker/main.d.ts +7 -0
- package/dist/native-worker/main.js +74 -0
- package/dist/native-worker/protocol.d.ts +744 -0
- package/dist/native-worker/protocol.js +200 -0
- package/dist/native-worker/sandbox-executor.d.ts +68 -0
- package/dist/native-worker/sandbox-executor.js +210 -0
- package/dist/native-worker/stdio.d.ts +29 -0
- package/dist/native-worker/stdio.js +188 -0
- package/dist/native-worker/warm-delivery.d.ts +16 -0
- package/dist/native-worker/warm-delivery.js +33 -0
- package/dist/native-worker/warm-pool-ledger.d.ts +39 -0
- package/dist/native-worker/warm-pool-ledger.js +73 -0
- package/dist/native-worker/warm-pool.d.ts +107 -0
- package/dist/native-worker/warm-pool.js +283 -0
- package/dist/native-worker/worker.d.ts +17 -0
- package/dist/native-worker/worker.js +115 -0
- package/dist/providers/auth/authorization-server.d.ts +3 -0
- package/dist/providers/auth/index.js +2 -0
- package/dist/providers/auth/self-hosted.d.ts +13 -1
- package/dist/providers/auth/self-hosted.js +54 -4
- package/dist/providers/chat/fake.d.ts +46 -0
- package/dist/providers/chat/fake.js +39 -0
- package/dist/providers/chat/index.d.ts +4 -0
- package/dist/providers/chat/index.js +8 -0
- package/dist/providers/chat/slack.d.ts +37 -0
- package/dist/providers/chat/slack.js +105 -0
- package/dist/providers/chat/types.d.ts +42 -0
- package/dist/providers/chat/types.js +19 -0
- package/dist/providers/engine/types.d.ts +19 -0
- package/dist/providers/engine/types.js +22 -0
- package/dist/providers/executor/composition.d.ts +24 -1
- package/dist/providers/executor/composition.js +39 -6
- package/dist/providers/executor/container.d.ts +24 -1
- package/dist/providers/executor/container.js +101 -11
- package/dist/providers/executor/dbos.d.ts +42 -0
- package/dist/providers/executor/dbos.js +118 -12
- package/dist/providers/executor/deferred.d.ts +56 -0
- package/dist/providers/executor/deferred.js +119 -0
- package/dist/providers/executor/routing.d.ts +37 -10
- package/dist/providers/executor/routing.js +73 -32
- package/dist/providers/executor/types.d.ts +12 -0
- package/dist/providers/jobs/docker.js +3 -3
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +21 -2
- package/dist/providers/jobs/fake-kubernetes-api.js +42 -1
- package/dist/providers/jobs/kubernetes-api.d.ts +17 -1
- package/dist/providers/jobs/kubernetes-api.js +7 -0
- package/dist/providers/jobs/kubernetes-client.d.ts +10 -1
- package/dist/providers/jobs/kubernetes-client.js +52 -3
- package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +6 -1
- package/dist/providers/jobs/kubernetes-dry-run-fixture.js +6 -3
- package/dist/providers/jobs/kubernetes-isolation.d.ts +3 -1
- package/dist/providers/jobs/kubernetes-isolation.js +6 -0
- package/dist/providers/jobs/kubernetes-platform.d.ts +4 -1
- package/dist/providers/jobs/kubernetes-platform.js +38 -1
- package/dist/providers/jobs/kubernetes-preflight.d.ts +2 -1
- package/dist/providers/jobs/kubernetes-preflight.js +4 -2
- package/dist/providers/jobs/kubernetes.d.ts +36 -1
- package/dist/providers/jobs/kubernetes.js +74 -4
- package/dist/providers/jobs/metadata-probes.d.ts +11 -0
- package/dist/providers/jobs/metadata-probes.js +13 -0
- package/dist/providers/jobs/types.d.ts +9 -0
- package/dist/providers/review-host/github.d.ts +11 -1
- package/dist/providers/review-host/github.js +50 -0
- package/dist/providers/review-host/types.d.ts +23 -0
- package/dist/providers/vcs/github.d.ts +32 -6
- package/dist/providers/vcs/github.js +74 -16
- package/dist/quickstart/coding-seed.d.ts +10 -3
- package/dist/quickstart/coding-seed.js +74 -3
- package/dist/quickstart/images.d.ts +2 -0
- package/dist/quickstart/images.js +7 -1
- package/dist/quickstart/reviewer-prompt.d.ts +1 -1
- package/dist/quickstart/reviewer-prompt.js +1 -1
- package/dist/quickstart-images.json +1 -1
- package/dist/sandbox/brokered-fetch.d.ts +23 -0
- package/dist/sandbox/brokered-fetch.js +37 -0
- package/dist/sandbox/host-functions.d.ts +34 -0
- package/dist/sandbox/host-functions.js +144 -80
- package/dist/sandbox/prelude.js +7 -1
- package/dist/sandbox/run-in-sandbox.d.ts +19 -0
- package/dist/sandbox/run-in-sandbox.js +28 -10
- package/dist/sandbox/safe-fetch.d.ts +2 -0
- package/dist/sandbox/safe-fetch.js +3 -1
- package/dist/sandbox/secret-broker-sigv4.d.ts +2 -0
- package/dist/sandbox/secret-broker-sigv4.js +49 -0
- package/dist/sandbox/secret-broker.d.ts +34 -0
- package/dist/sandbox/secret-broker.js +162 -0
- package/dist/sandbox/user-tool.d.ts +14 -0
- package/dist/sandbox/user-tool.js +32 -0
- package/dist/serve.js +18 -0
- package/dist/viewer/api-schema.d.ts +210 -14
- package/dist/viewer/api-schema.js +22 -0
- package/dist/viewer/build-schemas.js +4 -1
- package/dist/viewer/event-bus.d.ts +6 -0
- package/dist/viewer/event-bus.js +16 -7
- package/dist/viewer/graph.d.ts +5 -2
- package/dist/viewer/graph.js +7 -2
- package/dist/viewer/http.d.ts +0 -1
- package/dist/viewer/http.js +2 -2
- package/dist/viewer/infra.js +25 -2
- package/dist/viewer/limits.d.ts +4 -0
- package/dist/viewer/limits.js +4 -0
- package/dist/viewer/openapi.d.ts +15 -0
- package/dist/viewer/openapi.js +172 -0
- package/docs/README.md +7 -0
- package/docs/agent-recipes.md +57 -8
- package/docs/architecture-runtime.md +16 -1
- package/docs/code-review-agents.md +139 -5
- package/docs/coding-agent-setup.md +113 -5
- package/docs/coding-packages.md +4 -2
- package/docs/coding-services.md +3 -1
- package/docs/coding-worker-byo-images.md +198 -6
- package/docs/coding-worker-isolation.md +68 -14
- package/docs/getting-started-gke.md +225 -9
- package/docs/getting-started-identity-provider.md +21 -10
- package/docs/getting-started.md +5 -4
- package/docs/jira-agents.md +5 -1
- package/docs/native-sandbox.md +635 -0
- package/docs/release-verification.md +9 -0
- package/docs/security-deployment.md +113 -12
- package/docs/slack-notifications.md +252 -0
- package/docs/tool-secrets.md +252 -0
- package/docs/viewer-api.md +46 -5
- package/docs/viewer-api.openapi.yml +1404 -0
- package/help/admin-viewer.md +6 -2
- package/help/agent-recipes.md +27 -0
- package/help/architecture-agent.md +1 -1
- package/help/brokered-secrets.md +79 -0
- package/help/build-claude-code-image.md +131 -0
- package/help/build-worker-image.md +3 -6
- package/help/code-review-agents.md +68 -6
- package/help/deploy-gke.md +8 -1
- package/help/deployment-targets.md +25 -14
- package/help/errors/coding-provider-not-configured.md +2 -2
- package/help/errors/database-auth-invalid.md +28 -0
- package/help/errors/github-account-not-allowed.md +25 -0
- package/help/errors/low-power-disabled.md +29 -0
- package/help/errors/low-power-scale-forbidden.md +35 -0
- package/help/errors/low-power-wake-timeout.md +30 -0
- package/help/errors/mobile-disabled.md +31 -0
- package/help/errors/native-sandbox-capacity.md +22 -0
- package/help/errors/native-sandbox-deadline-exceeded.md +19 -0
- package/help/errors/native-sandbox-docker-failed.md +20 -0
- package/help/errors/native-sandbox-gateway-unavailable.md +21 -0
- package/help/errors/native-sandbox-image-not-pinned.md +19 -0
- package/help/errors/native-sandbox-isolation-mismatch.md +20 -0
- package/help/errors/native-sandbox-network-unenforced.md +22 -0
- package/help/errors/native-sandbox-requires-catalog.md +31 -0
- package/help/errors/native-sandbox-unavailable.md +19 -0
- package/help/errors/native-sandbox-warm-delivery-failed.md +21 -0
- package/help/errors/native-sandbox-worker-exited.md +20 -0
- package/help/errors/native-sandbox-worker-lost.md +20 -0
- package/help/errors/native-sandbox-worker-unready.md +22 -0
- package/help/errors/secret-broker-body-invalid.md +26 -0
- package/help/errors/secret-broker-changed.md +20 -0
- package/help/errors/secret-broker-config-invalid.md +30 -0
- package/help/errors/secret-broker-conflict.md +27 -0
- package/help/errors/secret-broker-destination-denied.md +28 -0
- package/help/errors/secret-broker-value-invalid.md +28 -0
- package/help/errors/secret-brokered.md +24 -0
- package/help/errors/secret-not-brokered.md +25 -0
- package/help/errors/slack-auth-failed.md +48 -0
- package/help/errors/slack-channel-unreachable.md +39 -0
- package/help/errors/slack-not-configured.md +33 -0
- package/help/getting-started.md +4 -5
- package/help/github.md +18 -1
- package/help/identity-and-access.md +5 -1
- package/help/local-repositories.md +2 -3
- package/help/low-power-mode.md +125 -0
- package/help/merge-order-check.md +117 -0
- package/help/mobile-app.md +54 -0
- package/help/native-sandbox.md +136 -0
- package/help/observability.md +8 -0
- package/help/related-pull-requests.md +70 -9
- package/help/repo-instructions-and-skills.md +91 -0
- package/help/review-fix-rounds.md +10 -0
- package/help/slack-notifications.md +62 -0
- package/help/troubleshooting/coding-workers.md +21 -0
- package/package.json +11 -4
- package/prisma/migrations/20261009000003_native_execution_mode/migration.sql +12 -0
- package/prisma/migrations/20261009000004_native_gateway_ledger/migration.sql +65 -0
- package/prisma/migrations/20261009000005_native_gateway_call_child_agent/migration.sql +5 -0
- package/prisma/migrations/20261009000006_run_deferred_start_stop/migration.sql +14 -0
- package/prisma/migrations/20261009000007_native_gateway_network_ready/migration.sql +5 -0
- package/prisma/migrations/20261010000001_workflow_notifications/migration.sql +99 -0
- package/prisma/migrations/20261011000001_native_gateway_session_status_index/migration.sql +2 -0
- package/prisma/migrations/20261012000001_native_warm_worker/migration.sql +32 -0
- package/prisma/migrations/20261013000001_coding_run_merge_order/migration.sql +2 -0
- package/prisma/migrations/20261013000001_secret_broker/migration.sql +17 -0
- package/prisma/migrations/20261013000002_deferred_review_request/migration.sql +4 -0
- package/prisma/migrations/20261014000000_repo_skills/migration.sql +15 -0
- package/prisma/migrations/20261015000001_coding_run_merge_order_index/migration.sql +2 -0
- package/prisma/migrations/20261015000002_no_change_rereview/migration.sql +2 -0
- package/prisma/schema.prisma +362 -91
|
@@ -79,15 +79,15 @@ Scopes and roles do different jobs:
|
|
|
79
79
|
- **Roles authorize.** A user has a set of roles. With no roles, the user is a
|
|
80
80
|
member:
|
|
81
81
|
|
|
82
|
-
| Role | Grants
|
|
83
|
-
| ------------------ |
|
|
84
|
-
| `admin` | `agents:admin`, `packages:approve`, `services:manage`, `admin:view` and `
|
|
85
|
-
| `package-approver` | `packages:approve`
|
|
86
|
-
| `service-manager` | `services:manage`
|
|
87
|
-
| `model-manager` | `models:admin`
|
|
88
|
-
| (none) | nothing privileged; every other scope works as the token allows
|
|
82
|
+
| Role | Grants |
|
|
83
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------ |
|
|
84
|
+
| `admin` | `agents:admin`, `packages:approve`, `services:manage`, `admin:view`, `models:admin` and `power:manage` |
|
|
85
|
+
| `package-approver` | `packages:approve` |
|
|
86
|
+
| `service-manager` | `services:manage` |
|
|
87
|
+
| `model-manager` | `models:admin` |
|
|
88
|
+
| (none) | nothing privileged; every other scope works as the token allows |
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
Eight operations are privileged:
|
|
91
91
|
|
|
92
92
|
- `make_owner`, which reassigns any agent's owner, including another
|
|
93
93
|
principal's private agent (see [Sharing agents](#sharing-agents) for what
|
|
@@ -104,7 +104,10 @@ Seven operations are privileged:
|
|
|
104
104
|
(`set_model`, `disable_model`, `reset_model`; reading the catalog is
|
|
105
105
|
`agents:read`, see [models.md](models.md));
|
|
106
106
|
- reading every owner's runs through the admin viewer API (see
|
|
107
|
-
[viewer-api.md](viewer-api.md))
|
|
107
|
+
[viewer-api.md](viewer-api.md));
|
|
108
|
+
- reading low-power state and scaling the coding proxy and native gateway to
|
|
109
|
+
zero now (`power_status`, `power_sleep`; see
|
|
110
|
+
[Low-power mode](getting-started-gke.md#low-power-mode)).
|
|
108
111
|
|
|
109
112
|
Each needs **both** its scope on the token **and** a role that grants that
|
|
110
113
|
permission:
|
|
@@ -114,10 +117,12 @@ permission:
|
|
|
114
117
|
- Service catalog changes need `services:manage`.
|
|
115
118
|
- Model catalog changes need `models:admin`.
|
|
116
119
|
- The admin viewer API needs `admin:view`, which only the `admin` role grants.
|
|
120
|
+
- `power_status` and `power_sleep` need `power:manage`, which only the `admin`
|
|
121
|
+
role grants.
|
|
117
122
|
|
|
118
123
|
In practice:
|
|
119
124
|
|
|
120
|
-
- an `admin` can do all
|
|
125
|
+
- an `admin` can do all eight;
|
|
121
126
|
- a `package-approver` can approve packages only;
|
|
122
127
|
- a `service-manager` can change the service catalog only;
|
|
123
128
|
- a `model-manager` can change the model catalog only;
|
|
@@ -190,7 +195,10 @@ See the [Fetch standard](https://fetch.spec.whatwg.org/#append-a-request-origin-
|
|
|
190
195
|
|
|
191
196
|
Clients must re-register as public clients (`token_endpoint_auth_method=none`).
|
|
192
197
|
Only S256 PKCE and exact registered redirect strings are accepted. Redirects
|
|
193
|
-
must be HTTPS or loopback HTTP,
|
|
198
|
+
must be HTTPS or loopback HTTP, or, only with `WARDBY_MOBILE_ENABLED=true`,
|
|
199
|
+
exactly the configured mobile redirect (`WARDBY_MOBILE_REDIRECT_URI`, default
|
|
200
|
+
`com.wardby.mobile:/oauth`; see the `mobile-app` help article), without
|
|
201
|
+
credentials or fragments. Registration
|
|
194
202
|
allows 1-10 redirects and a bounded client name. `AUTH_MAX_CLIENTS` defaults to
|
|
195
203
|
1000; PostgreSQL serializes capacity checks and shares rate limits across
|
|
196
204
|
processes. There is no confidential-client support or client secret.
|
|
@@ -456,6 +464,15 @@ stale, whichever executor id owns it. Set a fixed id only for a single,
|
|
|
456
464
|
long-lived process that should re-drive its own runs at launch rather than
|
|
457
465
|
after the heartbeat timeout.
|
|
458
466
|
|
|
467
|
+
An owner that is stalled but still alive (event-loop or database-pool
|
|
468
|
+
starvation long enough for its heartbeat to go stale) can overlap the attempt
|
|
469
|
+
another process adopted. The first attempt to record a step keeps the run; the
|
|
470
|
+
other stops at that step without writing the run or sending any
|
|
471
|
+
notifications, and DBOS parks it as a duplicate execution. That stopped step's
|
|
472
|
+
model spend is discarded rather than counted against the run, so look for the
|
|
473
|
+
`run_ownership_lost` warning in the server logs (it carries the run id, the
|
|
474
|
+
step, and the discarded usage when known) to see how often this happens.
|
|
475
|
+
|
|
459
476
|
**New data at rest.** Durable execution checkpoints every step's result into
|
|
460
477
|
`dbos.operation_outputs`: each turn's assistant text, every tool call's
|
|
461
478
|
arguments, every tool result in full, and the `load` step's pinned agent
|
|
@@ -543,6 +560,23 @@ bound connection pools and concurrent invocations, and review a cancellable
|
|
|
543
560
|
database adapter or isolated worker if strict immediate termination is required.
|
|
544
561
|
Do not claim these per-invocation caps establish a whole-process memory ceiling.
|
|
545
562
|
|
|
563
|
+
## Slack workflow notifications
|
|
564
|
+
|
|
565
|
+
This integration requires Wardby 0.6.0 or later.
|
|
566
|
+
|
|
567
|
+
Optional Slack workflow notifications add no inbound endpoint: wardby only
|
|
568
|
+
ever calls out to Slack's `chat.postMessage`/`chat.update`/`conversations.info`,
|
|
569
|
+
and the app manifest requests no event subscriptions or interactivity, so
|
|
570
|
+
nothing posted in Slack can start or affect a run. What reaches Slack is
|
|
571
|
+
limited to issue keys/titles and their links, pull request numbers and
|
|
572
|
+
links, agent names, review verdicts, fix-round numbers, a failed run's
|
|
573
|
+
reason (its first line, at most 200 characters), and (only when a link opts
|
|
574
|
+
in) the run's spend line — never code, diffs, review bodies, or run output.
|
|
575
|
+
Issue titles are posted regardless of Jira issue security, so link a project
|
|
576
|
+
only to a channel whose members may see every issue in it. The bot token is a provider credential like any other and never
|
|
577
|
+
reaches a sandboxed tool or coding-run worker. See
|
|
578
|
+
[Send workflow updates to Slack](slack-notifications.md).
|
|
579
|
+
|
|
546
580
|
## Coding runs on Kubernetes
|
|
547
581
|
|
|
548
582
|
`JOB_LAUNCHER=kubernetes` runs each coding agent in its own pod instead of a
|
|
@@ -565,7 +599,7 @@ connects from inside the pod to a destination that must be blocked and requires
|
|
|
565
599
|
three consecutive refusals. A cluster that does not enforce policy, or has not
|
|
566
600
|
yet programmed this pod's rules, never reaches the point of running agent code.
|
|
567
601
|
The same check runs at startup against a throwaway canary pod, which also
|
|
568
|
-
verifies the pod cannot reach DNS, the internet or the cloud metadata
|
|
602
|
+
verifies the pod cannot reach DNS, the internet or the cloud metadata endpoints.
|
|
569
603
|
|
|
570
604
|
**RBAC.** The control plane needs a namespace Role (`pods`, `pods/exec`,
|
|
571
605
|
`pods/log`, `secrets`, `configmaps`, `networkpolicies`, `services`) and a
|
|
@@ -579,6 +613,15 @@ has none, so that configuration is development-only and says so. Set
|
|
|
579
613
|
`KUBERNETES_RUNTIME_CLASS` to the cluster's sandboxed runtime class in
|
|
580
614
|
production; the launcher warns loudly when it is unset.
|
|
581
615
|
|
|
616
|
+
The `eks` platform profile (Amazon EKS with a gVisor node group) also requires
|
|
617
|
+
the `gvisor` runtime class. The cluster supplies a RuntimeClass `gvisor`
|
|
618
|
+
(handler `runsc`) whose scheduling block targets nodes labelled
|
|
619
|
+
`wardby.dev/sandbox=gvisor` and tainted `sandbox=gvisor:NoSchedule`; coding-pod attestation
|
|
620
|
+
forgives that node selector and toleration and nothing else. The startup canary
|
|
621
|
+
and the native sandbox gate probe the cloud metadata endpoints
|
|
622
|
+
`169.254.169.254`, `169.254.170.23` and `fd00:ec2::23` (EKS Pod Identity agent, IPv4 and IPv6) and
|
|
623
|
+
`fd00:ec2::254` (EC2 IPv6), all on port 80, and require every one to be unreachable.
|
|
624
|
+
|
|
582
625
|
The `gke-autopilot` platform profile contains narrow admission allowances
|
|
583
626
|
captured from a real cluster and requires the `gvisor` runtime class. A dry-run
|
|
584
627
|
capture cannot observe labels added after pod scheduling, so live-run behavior
|
|
@@ -592,6 +635,52 @@ Per-run record ConfigMaps currently require operator-managed garbage collection,
|
|
|
592
635
|
and the real-cluster suite does not yet cover every Docker containment
|
|
593
636
|
scenario.
|
|
594
637
|
|
|
638
|
+
## Database authentication
|
|
639
|
+
|
|
640
|
+
By default `DATABASE_URL` carries the database password. On Amazon RDS (or
|
|
641
|
+
Aurora) for PostgreSQL, set `DATABASE_AUTH=rds-iam` to authenticate with IAM
|
|
642
|
+
database authentication instead: the password is a short-lived token signed with
|
|
643
|
+
the workload's AWS credentials (for example EKS Pod Identity), minted when a
|
|
644
|
+
connection opens. Any other value is refused with
|
|
645
|
+
[`database_auth_invalid`](../help/errors/database-auth-invalid.md).
|
|
646
|
+
|
|
647
|
+
Under `rds-iam`:
|
|
648
|
+
|
|
649
|
+
- `DATABASE_URL` must be `postgresql://` (or `postgres://`) with the database
|
|
650
|
+
user and no password, and must contain `sslmode=verify-full` and
|
|
651
|
+
`sslrootcert=<path to the RDS CA bundle>`. The port defaults to 5432.
|
|
652
|
+
- The region comes from `DATABASE_AWS_REGION`, else `AWS_REGION`.
|
|
653
|
+
- The database user must be granted `rds_iam` and the workload's IAM role must
|
|
654
|
+
allow `rds-db:connect` for it.
|
|
655
|
+
- Tokens are valid for 15 minutes and only for opening a connection; Wardby
|
|
656
|
+
reuses one for 10 minutes, and open connections outlive their token.
|
|
657
|
+
- It applies to every app connection: the Prisma clients (server, scheduler,
|
|
658
|
+
coding proxy, native gateway), the DBOS system database
|
|
659
|
+
(`DBOS_SYSTEM_DATABASE_URL`, else `DATABASE_URL`, under the same rules) and
|
|
660
|
+
the viewer's LISTEN connection. The DBOS system pool holds up to 10
|
|
661
|
+
connections; count it in the database's connection budget.
|
|
662
|
+
- URL parameters that are carried over: `application_name`,
|
|
663
|
+
`fallback_application_name`, `options`, `client_encoding`,
|
|
664
|
+
`statement_timeout`, `lock_timeout`, `idle_in_transaction_session_timeout`,
|
|
665
|
+
`query_timeout`. `connection_limit` and `pool_timeout` still size and bound
|
|
666
|
+
the pool, `connect_timeout` (seconds) applies to the DBOS pool, and `schema`
|
|
667
|
+
is accepted with no run-time effect, as in password mode. Every other
|
|
668
|
+
parameter is refused by name, including `sslcert`, `sslkey`, `ssl`, `host` and
|
|
669
|
+
`pgbouncer`; the Cloud SQL `sslcert=` advice does not apply to RDS.
|
|
670
|
+
- A misconfigured setup fails at process start, for every `wardby` command,
|
|
671
|
+
because the database module is loaded at start.
|
|
672
|
+
- `prisma migrate deploy` and `dbos schema` take a URL, not a connection
|
|
673
|
+
config, so they are not covered. Mint a short-lived URL with the helper
|
|
674
|
+
shipped in the migration image and run them within its 15 minutes:
|
|
675
|
+
|
|
676
|
+
```bash
|
|
677
|
+
DATABASE_URL="$(node scripts/rds-iam-url.mjs)" && export DATABASE_URL && npm run prisma:migrate && npm run dbos:migrate
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
The helper reads `DATABASE_URL`, `DATABASE_AWS_REGION`/`AWS_REGION` and the
|
|
681
|
+
ambient AWS credentials, and prints a URL containing a credential: never log
|
|
682
|
+
its output. `wardby quickstart` does not support `rds-iam`.
|
|
683
|
+
|
|
595
684
|
## Coding package registry
|
|
596
685
|
|
|
597
686
|
Enabling a coding agent's package allowlist widens the trusted proxy's own
|
|
@@ -613,6 +702,18 @@ guarantee; and the OSV vulnerability audit fails **closed**
|
|
|
613
702
|
operator explicitly sets `REGISTRY_AUDIT_FAIL_OPEN=true` to allow installs
|
|
614
703
|
through unaudited during an OSV outage.
|
|
615
704
|
|
|
705
|
+
## Native sandbox
|
|
706
|
+
|
|
707
|
+
A native agent set to `nativeExecutionMode=sandbox` runs its turn loop and user
|
|
708
|
+
tools in a single-use container with no credentials, database access, Docker
|
|
709
|
+
socket, or network except the native gateway. The gateway is a trusted
|
|
710
|
+
component: it holds the LLM credentials and integration settings, so give it
|
|
711
|
+
the database and provider settings it needs and nothing else, never the Docker
|
|
712
|
+
socket, and do not publish its port outside the Docker host. Only the server,
|
|
713
|
+
which launches workers, needs Docker access (or, on Kubernetes, permission to
|
|
714
|
+
create pods in the run namespace). See
|
|
715
|
+
[Native sandbox](native-sandbox.md).
|
|
716
|
+
|
|
616
717
|
## Images and dependencies
|
|
617
718
|
|
|
618
719
|
```sh
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Send workflow updates to Slack
|
|
2
|
+
|
|
3
|
+
> **Requires Wardby 0.6.0 or later.**
|
|
4
|
+
|
|
5
|
+
Link a Slack channel to a Jira project or to an agent (native or coding), and wardby posts
|
|
6
|
+
that project's or agent's workflow updates there: a card picked up, a pull
|
|
7
|
+
request opened, a review verdict, fix rounds, and the merge — one thread per
|
|
8
|
+
card. This is outbound only: nothing in Slack starts or affects a run, and
|
|
9
|
+
wardby exposes no new inbound endpoint for it.
|
|
10
|
+
|
|
11
|
+
## What it does
|
|
12
|
+
|
|
13
|
+
### Events
|
|
14
|
+
|
|
15
|
+
Six kinds of lifecycle event can post to a linked channel:
|
|
16
|
+
|
|
17
|
+
| Kind | Posts when | Content |
|
|
18
|
+
| ----------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
|
|
19
|
+
| `issue_picked_up` | A Jira event starts a run on a linked issue | Issue key, title, and link; agent name; trigger kind |
|
|
20
|
+
| `run_failed` | A top-level run ends `failed`, `refused`, `budget_exhausted`, `cancelled`, or `lost` | Agent name, status, a short first-line reason (never the full error) |
|
|
21
|
+
| `pr_opened` | A coding run opens a pull request | Repository#number and link, the issue it is for, any Jira status move |
|
|
22
|
+
| `review_posted` | wardby's own review check posts a verdict | `APPROVE` / `CHANGES_REQUESTED` / `COMMENT`, the reviewer agent, the PR link |
|
|
23
|
+
| `review_fix` | An automatic [fix round](../help/review-fix-rounds.md) starts or hits the cap | Round number of the cap, started or capped |
|
|
24
|
+
| `pr_closed` | A pull request is merged or closed | Merged or closed, any Jira status move |
|
|
25
|
+
|
|
26
|
+
A run finishing successfully is not its own event — on the workflow it shows
|
|
27
|
+
up as `pr_opened` or `review_posted` already. Child coding runs started by a
|
|
28
|
+
parent surface through the parent's own `run_failed`, not their own.
|
|
29
|
+
|
|
30
|
+
Some runs do not post `run_failed` at all:
|
|
31
|
+
|
|
32
|
+
- a coding agent's run triggered directly (rather than as a child of a
|
|
33
|
+
native agent's run),
|
|
34
|
+
- a review verdict or failure from a coding agent acting as the reviewer, and
|
|
35
|
+
- runs started from the `wardby run` CLI command.
|
|
36
|
+
|
|
37
|
+
A pull request linked to several issues posts `pr_opened` and `pr_closed`
|
|
38
|
+
only to the first linked issue's thread.
|
|
39
|
+
|
|
40
|
+
### Threads
|
|
41
|
+
|
|
42
|
+
Each channel gets one thread per card: one per Jira issue (when the event has
|
|
43
|
+
one) or one per pull request (when it doesn't). The first event for a card
|
|
44
|
+
posts a parent message naming the issue or pull request; every later event
|
|
45
|
+
for the same card is a reply in that thread, and the parent is kept updated
|
|
46
|
+
with a short status line. The statuses are:
|
|
47
|
+
|
|
48
|
+
| Status | Set by |
|
|
49
|
+
| ---------------------- | ---------------------------------------------------------------- |
|
|
50
|
+
| `picked up` | `issue_picked_up` on a new thread, or after `merged ✅`/`closed` |
|
|
51
|
+
| `PR open` | `pr_opened` |
|
|
52
|
+
| `changes requested` | a `CHANGES_REQUESTED` review |
|
|
53
|
+
| `approved` | an `APPROVE` review |
|
|
54
|
+
| `fixing` | a fix round starting (the round number is in the thread reply) |
|
|
55
|
+
| `fix rounds exhausted` | fix rounds reaching the cap with changes still requested |
|
|
56
|
+
| `merged ✅` | the pull request merged |
|
|
57
|
+
| `closed` | the pull request closed without merging |
|
|
58
|
+
| `failed ❌` | `run_failed` |
|
|
59
|
+
|
|
60
|
+
A `COMMENT` review leaves the status as it was. `merged ✅` and `closed` stick:
|
|
61
|
+
a late review, fix round, failure, or repeated close does not change them.
|
|
62
|
+
Only a new start does — the card picked up again, or a new pull request
|
|
63
|
+
opened for it — which sets `picked up` or `PR open` again.
|
|
64
|
+
|
|
65
|
+
Most events only post as a thread reply. A merge and a top-level run failure
|
|
66
|
+
also post to the channel itself, so they are visible without opening the
|
|
67
|
+
thread.
|
|
68
|
+
|
|
69
|
+
### What is never sent
|
|
70
|
+
|
|
71
|
+
wardby never posts code, diffs, review bodies, or run output to Slack. Error
|
|
72
|
+
messages shown in Slack are a short first line only (at most 200 characters),
|
|
73
|
+
never a full error or stack trace.
|
|
74
|
+
|
|
75
|
+
## 1. Create the Slack app
|
|
76
|
+
|
|
77
|
+
Use the manifest in [`deploy/slack/app-manifest.yaml`](../deploy/slack/app-manifest.yaml):
|
|
78
|
+
|
|
79
|
+
1. Open [api.slack.com/apps](https://api.slack.com/apps), choose **Create New
|
|
80
|
+
App → From a manifest**, pick your workspace, and paste the manifest.
|
|
81
|
+
2. On **OAuth & Permissions**, click **Install to Workspace** and approve the
|
|
82
|
+
requested scopes.
|
|
83
|
+
3. Copy the **Bot User OAuth Token** (starts `xoxb-`).
|
|
84
|
+
|
|
85
|
+
See [`deploy/slack/README.md`](../deploy/slack/README.md) for the full
|
|
86
|
+
walkthrough, including the optional per-agent display-name scope.
|
|
87
|
+
|
|
88
|
+
## 2. Configure wardby
|
|
89
|
+
|
|
90
|
+
| Variable | Value |
|
|
91
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
92
|
+
| `WARDBY_SLACK_BOT_TOKEN` | The bot token from step 1 (`xoxb-…`). Unset = Slack notifications are disabled. |
|
|
93
|
+
| `WARDBY_SLACK_API_BASE_URL` | Optional. Overrides the Slack Web API base URL (`https://slack.com/api`); must be `https`. |
|
|
94
|
+
| `WARDBY_SLACK_CUSTOMIZE` | Optional, `true` or `false` (default `false`). Needs `chat:write.customize` in the installed app. |
|
|
95
|
+
|
|
96
|
+
Store `WARDBY_SLACK_BOT_TOKEN` in your secrets backend the same way you store
|
|
97
|
+
other provider credentials (`GITHUB_APP_PRIVATE_KEY`, `WARDBY_JIRA_API_TOKEN`)
|
|
98
|
+
— never in a committed file. On the GKE reference deployment, see
|
|
99
|
+
[Getting started on GKE](getting-started-gke.md). Restart wardby after setting
|
|
100
|
+
it. The startup log line `chat notifications acting as` names the Slack team
|
|
101
|
+
and bot user id wardby authenticated as. If that check fails instead, wardby
|
|
102
|
+
only logs an error and still starts: it does not fail to boot, and delivery
|
|
103
|
+
is not paused up front. Delivery pauses when the first actual delivery fails
|
|
104
|
+
authentication (see [Failure modes](#failure-modes)).
|
|
105
|
+
|
|
106
|
+
With `WARDBY_SLACK_CUSTOMIZE=true`, a message about an event that names an
|
|
107
|
+
agent (`issue_picked_up`, `run_failed`, `review_posted`) is posted under that
|
|
108
|
+
agent's name; every other message, and every message when the option is off,
|
|
109
|
+
posts as `wardby`. A thread's parent message uses the name of the event that
|
|
110
|
+
started the thread. wardby sets no icon.
|
|
111
|
+
|
|
112
|
+
Without `WARDBY_SLACK_BOT_TOKEN`, `link_notification_channel` and
|
|
113
|
+
`test_notification_channel` are refused and the dispatcher does not start;
|
|
114
|
+
`unlink_notification_channel` and `list_notification_channels` still work, so
|
|
115
|
+
you can clean up old links. See
|
|
116
|
+
[`errors/slack-not-configured`](../help/errors/slack-not-configured.md).
|
|
117
|
+
|
|
118
|
+
## Scopes and why
|
|
119
|
+
|
|
120
|
+
| Scope | Required | Used for |
|
|
121
|
+
| ---------------------- | ----------- | --------------------------------------------------------------------------------------------------------- |
|
|
122
|
+
| `chat:write` | Yes | Posting and updating the bot's own messages, including threaded replies |
|
|
123
|
+
| `chat:write.public` | Recommended | Posting to public channels without inviting the bot first |
|
|
124
|
+
| `channels:read` | Recommended | Validating a channel id and recording its name when linking |
|
|
125
|
+
| `groups:read` | Recommended | The same, for private channels |
|
|
126
|
+
| `chat:write.customize` | Optional | Posting under the name of the agent an event is about instead of `wardby` (`WARDBY_SLACK_CUSTOMIZE=true`) |
|
|
127
|
+
|
|
128
|
+
Without `channels:read`/`groups:read`, linking still accepts a raw channel id
|
|
129
|
+
but skips validating it. Any other authentication error while linking (an
|
|
130
|
+
invalid or revoked token) refuses the link; see
|
|
131
|
+
[`errors/slack-auth-failed`](../help/errors/slack-auth-failed.md). Private channels always need `/invite @wardby` (or
|
|
132
|
+
whatever you named the app) regardless of scopes — Slack never lets a bot see
|
|
133
|
+
or post to a private channel it hasn't been invited to. `chat.postMessage` is
|
|
134
|
+
rate-limited to about one message per second per channel; wardby's dispatcher
|
|
135
|
+
paces its own posts to stay under that.
|
|
136
|
+
|
|
137
|
+
## Link channels
|
|
138
|
+
|
|
139
|
+
Use the `link_notification_channel` MCP tool. It needs `agents:admin` with
|
|
140
|
+
the admin role, the same trust model as `link_issue_project`: wardby cannot
|
|
141
|
+
verify a caller's own Slack workspace access, so an administrator approves
|
|
142
|
+
every link.
|
|
143
|
+
|
|
144
|
+
Link a channel to a Jira project:
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"channel": "C0123456789",
|
|
149
|
+
"projectKey": "PAY",
|
|
150
|
+
"issueProvider": "jira",
|
|
151
|
+
"events": ["issue_picked_up", "pr_opened", "review_posted", "pr_closed"],
|
|
152
|
+
"includeCost": true
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Link a channel to an agent instead (every event for that agent's runs, no
|
|
157
|
+
filter):
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"channel": "C0123456789",
|
|
162
|
+
"agentId": "<agent id>"
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
- Give exactly one of `projectKey` (with optional `issueProvider`, default
|
|
167
|
+
`jira`) or `agentId`.
|
|
168
|
+
- `channel` is the Slack channel id — `C…` for a public channel, `G…` for a
|
|
169
|
+
private one — never a `#name`. Find it in the channel's details in Slack
|
|
170
|
+
(**View channel details**, near the bottom). Passing a `#name` is refused.
|
|
171
|
+
- `events` narrows which of the six kinds post to this link; omit it (or pass
|
|
172
|
+
an empty list) for all six.
|
|
173
|
+
- `includeCost` appends the run's spend line to messages for this link.
|
|
174
|
+
- Invite the bot to any private channel before linking it:
|
|
175
|
+
`/invite @wardby` in that channel.
|
|
176
|
+
- Re-linking the same channel and subject replaces `events` and
|
|
177
|
+
`includeCost` and clears any previously recorded delivery error — send the
|
|
178
|
+
full desired state each time.
|
|
179
|
+
|
|
180
|
+
Then confirm delivery works before relying on it:
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{ "id": "<link id from link_notification_channel>" }
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
`test_notification_channel` posts "✅ wardby is connected to this channel." —
|
|
187
|
+
if the bot can't write there, you get the error immediately instead of
|
|
188
|
+
finding out when the first real event is dropped. A successful test also
|
|
189
|
+
clears the link's `lastError`.
|
|
190
|
+
|
|
191
|
+
`list_notification_channels` shows every link's `lastError` and its pending
|
|
192
|
+
and failed delivery counts (counted per channel: two links to the same
|
|
193
|
+
channel show the same counts); filter by `projectKey`, `agentId`, or `channel`.
|
|
194
|
+
Listing your own agent's links needs read access to that agent; listing
|
|
195
|
+
everything (or filtering by `projectKey`) needs `agents:admin` with the admin
|
|
196
|
+
role. `unlink_notification_channel` removes a link by `id`.
|
|
197
|
+
|
|
198
|
+
## Failure modes
|
|
199
|
+
|
|
200
|
+
- **Channel not found, bot not in channel, or channel archived.** That
|
|
201
|
+
channel's pending deliveries fail immediately and are never retried, and
|
|
202
|
+
every link to it shows the error in `lastError`. Invite the bot
|
|
203
|
+
(`/invite @wardby`) or otherwise fix the channel in Slack. New events
|
|
204
|
+
deliver as soon as the bot can post there again; the deliveries that
|
|
205
|
+
already failed are not resent. Re-linking the channel (or a successful
|
|
206
|
+
`test_notification_channel`) clears `lastError`. See
|
|
207
|
+
[`errors/slack-channel-unreachable`](../help/errors/slack-channel-unreachable.md).
|
|
208
|
+
- **Invalid or revoked token.** Delivery pauses for every linked channel (no
|
|
209
|
+
deliveries are lost — they stay pending), and wardby re-checks the token
|
|
210
|
+
every five minutes with Slack's `auth.test`; it resumes automatically once
|
|
211
|
+
the check succeeds. See
|
|
212
|
+
[`errors/slack-auth-failed`](../help/errors/slack-auth-failed.md).
|
|
213
|
+
- **A missing scope.** Delivery pauses the same way, but `auth.test` needs no
|
|
214
|
+
scope, so the five-minute check succeeds, the next delivery fails again,
|
|
215
|
+
and delivery pauses again. It does not fix itself: add the scope to the app
|
|
216
|
+
and reinstall it to the workspace (and if Slack issues a new token, set it
|
|
217
|
+
and restart wardby). Pending deliveries are kept and sent once it works.
|
|
218
|
+
- **Rate limits.** wardby paces its own posts to about one per second per
|
|
219
|
+
channel; if Slack still responds with a rate-limit error, that delivery is
|
|
220
|
+
retried after the delay Slack specifies, with no attempt counted against
|
|
221
|
+
the retry limit below.
|
|
222
|
+
- **Transient errors** (network issues, Slack 5xx responses) are retried with
|
|
223
|
+
increasing back-off, up to 10 attempts, before the delivery is marked
|
|
224
|
+
failed.
|
|
225
|
+
- **Events while Slack isn't configured.** An event recorded before
|
|
226
|
+
`WARDBY_SLACK_BOT_TOKEN` is set is not queued and is not delivered once you
|
|
227
|
+
configure it — only events recorded after Slack notifications are enabled
|
|
228
|
+
reach Slack.
|
|
229
|
+
- **Duplicates.** Delivery is at least once: if wardby crashes or loses its
|
|
230
|
+
database connection right after Slack accepts a message, that message can
|
|
231
|
+
be posted again. A rare duplicate thread reply is possible.
|
|
232
|
+
- **Retention.** Delivery records are kept for 30 days and then pruned.
|
|
233
|
+
|
|
234
|
+
## Security
|
|
235
|
+
|
|
236
|
+
Phase 1 is outbound only: wardby requests no event subscriptions and no
|
|
237
|
+
interactivity in the manifest, so there is no new inbound endpoint and
|
|
238
|
+
nothing posted in Slack can start or affect a run.
|
|
239
|
+
|
|
240
|
+
What leaves to Slack: issue keys, titles, and their links; pull request
|
|
241
|
+
numbers and links; agent names; review verdicts; fix-round numbers; a failed
|
|
242
|
+
run's reason (its first line, at most 200 characters); and, only when a
|
|
243
|
+
link's `includeCost` is on, the run's spend line. wardby never posts code,
|
|
244
|
+
diffs, review bodies, or run output, and an error message shown in Slack is a
|
|
245
|
+
short first line only, never a full error or stack trace.
|
|
246
|
+
|
|
247
|
+
Issue titles go to the linked channel regardless of Jira issue security: an
|
|
248
|
+
issue restricted by a Jira security level still has its key and title posted.
|
|
249
|
+
Link a project only to a channel whose members may see every issue in it.
|
|
250
|
+
|
|
251
|
+
The bot token stays on the wardby server; agents, sandboxed tools, and
|
|
252
|
+
coding-run workers never see it.
|