@smthrs/control 0.0.0-stage → 1.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +194 -0
- package/LICENSE +21 -0
- package/README.md +168 -2
- package/dist/cjs/ApprovalAuthority.d.ts +73 -0
- package/dist/cjs/ApprovalAuthority.d.ts.map +1 -0
- package/dist/cjs/ApprovalAuthority.js +62 -0
- package/dist/cjs/ApprovalAuthority.js.map +7 -0
- package/dist/cjs/Cancellation.d.ts +107 -0
- package/dist/cjs/Cancellation.d.ts.map +1 -0
- package/dist/cjs/Cancellation.js +72 -0
- package/dist/cjs/Cancellation.js.map +7 -0
- package/dist/cjs/Channels.d.ts +170 -0
- package/dist/cjs/Channels.d.ts.map +1 -0
- package/dist/cjs/Channels.js +278 -0
- package/dist/cjs/Channels.js.map +7 -0
- package/dist/cjs/Control.d.ts +202 -0
- package/dist/cjs/Control.d.ts.map +1 -0
- package/dist/cjs/Control.js +47 -0
- package/dist/cjs/Control.js.map +7 -0
- package/dist/cjs/ControlClient.d.ts +52 -0
- package/dist/cjs/ControlClient.d.ts.map +1 -0
- package/dist/cjs/ControlClient.js +191 -0
- package/dist/cjs/ControlClient.js.map +7 -0
- package/dist/cjs/ControlError.d.ts +318 -0
- package/dist/cjs/ControlError.d.ts.map +1 -0
- package/dist/cjs/ControlError.js +249 -0
- package/dist/cjs/ControlError.js.map +7 -0
- package/dist/cjs/ControlExecutor.d.ts +372 -0
- package/dist/cjs/ControlExecutor.d.ts.map +1 -0
- package/dist/cjs/ControlExecutor.js +123 -0
- package/dist/cjs/ControlExecutor.js.map +7 -0
- package/dist/cjs/ControlFacts.d.ts +454 -0
- package/dist/cjs/ControlFacts.d.ts.map +1 -0
- package/dist/cjs/ControlFacts.js +261 -0
- package/dist/cjs/ControlFacts.js.map +7 -0
- package/dist/cjs/ControlLive.d.ts +23 -0
- package/dist/cjs/ControlLive.d.ts.map +1 -0
- package/dist/cjs/ControlLive.js +1293 -0
- package/dist/cjs/ControlLive.js.map +7 -0
- package/dist/cjs/ControlRpcs.d.ts +1204 -0
- package/dist/cjs/ControlRpcs.d.ts.map +1 -0
- package/dist/cjs/ControlRpcs.js +247 -0
- package/dist/cjs/ControlRpcs.js.map +7 -0
- package/dist/cjs/ControlRuntime.d.ts +635 -0
- package/dist/cjs/ControlRuntime.d.ts.map +1 -0
- package/dist/cjs/ControlRuntime.js +744 -0
- package/dist/cjs/ControlRuntime.js.map +7 -0
- package/dist/cjs/ControlSchema.d.ts +2642 -0
- package/dist/cjs/ControlSchema.d.ts.map +1 -0
- package/dist/cjs/ControlSchema.js +634 -0
- package/dist/cjs/ControlSchema.js.map +7 -0
- package/dist/cjs/ControlServer.d.ts +51 -0
- package/dist/cjs/ControlServer.d.ts.map +1 -0
- package/dist/cjs/ControlServer.js +121 -0
- package/dist/cjs/ControlServer.js.map +7 -0
- package/dist/cjs/Credential.d.ts +136 -0
- package/dist/cjs/Credential.d.ts.map +1 -0
- package/dist/cjs/Credential.js +168 -0
- package/dist/cjs/Credential.js.map +7 -0
- package/dist/cjs/CredentialCipher.d.ts +90 -0
- package/dist/cjs/CredentialCipher.d.ts.map +1 -0
- package/dist/cjs/CredentialCipher.js +45 -0
- package/dist/cjs/CredentialCipher.js.map +7 -0
- package/dist/cjs/CredentialStore.d.ts +97 -0
- package/dist/cjs/CredentialStore.d.ts.map +1 -0
- package/dist/cjs/CredentialStore.js +81 -0
- package/dist/cjs/CredentialStore.js.map +7 -0
- package/dist/cjs/DispatchReader.d.ts +112 -0
- package/dist/cjs/DispatchReader.d.ts.map +1 -0
- package/dist/cjs/DispatchReader.js +45 -0
- package/dist/cjs/DispatchReader.js.map +7 -0
- package/dist/cjs/Health.d.ts +333 -0
- package/dist/cjs/Health.d.ts.map +1 -0
- package/dist/cjs/Health.js +311 -0
- package/dist/cjs/Health.js.map +7 -0
- package/dist/cjs/JevSessionChecker.d.ts +57 -0
- package/dist/cjs/JevSessionChecker.d.ts.map +1 -0
- package/dist/cjs/JevSessionChecker.js +113 -0
- package/dist/cjs/JevSessionChecker.js.map +7 -0
- package/dist/cjs/Lineage.d.ts +131 -0
- package/dist/cjs/Lineage.d.ts.map +1 -0
- package/dist/cjs/Lineage.js +81 -0
- package/dist/cjs/Lineage.js.map +7 -0
- package/dist/cjs/Migrations.d.ts +34 -0
- package/dist/cjs/Migrations.d.ts.map +1 -0
- package/dist/cjs/Migrations.js +60 -0
- package/dist/cjs/Migrations.js.map +7 -0
- package/dist/cjs/Monitor.d.ts +282 -0
- package/dist/cjs/Monitor.d.ts.map +1 -0
- package/dist/cjs/Monitor.js +283 -0
- package/dist/cjs/Monitor.js.map +7 -0
- package/dist/cjs/ScopedToken.d.ts +193 -0
- package/dist/cjs/ScopedToken.d.ts.map +1 -0
- package/dist/cjs/ScopedToken.js +135 -0
- package/dist/cjs/ScopedToken.js.map +7 -0
- package/dist/cjs/SqlControlRuntime.d.ts +161 -0
- package/dist/cjs/SqlControlRuntime.d.ts.map +1 -0
- package/dist/cjs/SqlControlRuntime.js +1522 -0
- package/dist/cjs/SqlControlRuntime.js.map +7 -0
- package/dist/cjs/SqlCredentialStore.d.ts +43 -0
- package/dist/cjs/SqlCredentialStore.d.ts.map +1 -0
- package/dist/cjs/SqlCredentialStore.js +113 -0
- package/dist/cjs/SqlCredentialStore.js.map +7 -0
- package/dist/cjs/Steering.d.ts +69 -0
- package/dist/cjs/Steering.d.ts.map +1 -0
- package/dist/cjs/Steering.js +49 -0
- package/dist/cjs/Steering.js.map +7 -0
- package/dist/cjs/SystemFlows.d.ts +223 -0
- package/dist/cjs/SystemFlows.d.ts.map +1 -0
- package/dist/cjs/SystemFlows.js +195 -0
- package/dist/cjs/SystemFlows.js.map +7 -0
- package/dist/cjs/WebCryptoCipher.d.ts +49 -0
- package/dist/cjs/WebCryptoCipher.d.ts.map +1 -0
- package/dist/cjs/WebCryptoCipher.js +129 -0
- package/dist/cjs/WebCryptoCipher.js.map +7 -0
- package/dist/cjs/WebhookChannel.d.ts +113 -0
- package/dist/cjs/WebhookChannel.d.ts.map +1 -0
- package/dist/cjs/WebhookChannel.js +98 -0
- package/dist/cjs/WebhookChannel.js.map +7 -0
- package/dist/cjs/index.d.ts +160 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +91 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/MutationBoundary.d.ts +27 -0
- package/dist/cjs/internal/MutationBoundary.d.ts.map +1 -0
- package/dist/cjs/internal/MutationBoundary.js +50 -0
- package/dist/cjs/internal/MutationBoundary.js.map +7 -0
- package/dist/cjs/internal/activeFibers.d.ts +12 -0
- package/dist/cjs/internal/activeFibers.d.ts.map +1 -0
- package/dist/cjs/internal/activeFibers.js +30 -0
- package/dist/cjs/internal/activeFibers.js.map +7 -0
- package/dist/cjs/internal/issues.d.ts +28 -0
- package/dist/cjs/internal/issues.d.ts.map +1 -0
- package/dist/cjs/internal/issues.js +34 -0
- package/dist/cjs/internal/issues.js.map +7 -0
- package/dist/cjs/internal/planning.d.ts +347 -0
- package/dist/cjs/internal/planning.d.ts.map +1 -0
- package/dist/cjs/internal/planning.js +137 -0
- package/dist/cjs/internal/planning.js.map +7 -0
- package/dist/cjs/internal/sqlSchemaErrors.d.ts +18 -0
- package/dist/cjs/internal/sqlSchemaErrors.d.ts.map +1 -0
- package/dist/cjs/internal/sqlSchemaErrors.js +40 -0
- package/dist/cjs/internal/sqlSchemaErrors.js.map +7 -0
- package/dist/cjs/migrations/0001_control_tables.d.ts +18 -0
- package/dist/cjs/migrations/0001_control_tables.d.ts.map +1 -0
- package/dist/cjs/migrations/0001_control_tables.js +115 -0
- package/dist/cjs/migrations/0001_control_tables.js.map +7 -0
- package/dist/cjs/migrations/0002_run_keys.d.ts +15 -0
- package/dist/cjs/migrations/0002_run_keys.d.ts.map +1 -0
- package/dist/cjs/migrations/0002_run_keys.js +44 -0
- package/dist/cjs/migrations/0002_run_keys.js.map +7 -0
- package/dist/cjs/migrations/0003_signal_commands.d.ts +13 -0
- package/dist/cjs/migrations/0003_signal_commands.d.ts.map +1 -0
- package/dist/cjs/migrations/0003_signal_commands.js +50 -0
- package/dist/cjs/migrations/0003_signal_commands.js.map +7 -0
- package/dist/cjs/migrations/0004_approval_decisions.d.ts +13 -0
- package/dist/cjs/migrations/0004_approval_decisions.d.ts.map +1 -0
- package/dist/cjs/migrations/0004_approval_decisions.js +45 -0
- package/dist/cjs/migrations/0004_approval_decisions.js.map +7 -0
- package/dist/cjs/migrations/0005_signal_principals.d.ts +18 -0
- package/dist/cjs/migrations/0005_signal_principals.d.ts.map +1 -0
- package/dist/cjs/migrations/0005_signal_principals.js +45 -0
- package/dist/cjs/migrations/0005_signal_principals.js.map +7 -0
- package/dist/cjs/migrations/0006_run_principals.d.ts +18 -0
- package/dist/cjs/migrations/0006_run_principals.d.ts.map +1 -0
- package/dist/cjs/migrations/0006_run_principals.js +49 -0
- package/dist/cjs/migrations/0006_run_principals.js.map +7 -0
- package/dist/cjs/migrations/0007_resume_consent.d.ts +18 -0
- package/dist/cjs/migrations/0007_resume_consent.d.ts.map +1 -0
- package/dist/cjs/migrations/0007_resume_consent.js +46 -0
- package/dist/cjs/migrations/0007_resume_consent.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/test/TestControl.d.ts +19 -0
- package/dist/cjs/test/TestControl.d.ts.map +1 -0
- package/dist/cjs/test/TestControl.js +62 -0
- package/dist/cjs/test/TestControl.js.map +7 -0
- package/dist/esm/ApprovalAuthority.d.ts +73 -0
- package/dist/esm/ApprovalAuthority.d.ts.map +1 -0
- package/dist/esm/ApprovalAuthority.js +72 -0
- package/dist/esm/ApprovalAuthority.js.map +1 -0
- package/dist/esm/Cancellation.d.ts +107 -0
- package/dist/esm/Cancellation.d.ts.map +1 -0
- package/dist/esm/Cancellation.js +116 -0
- package/dist/esm/Cancellation.js.map +1 -0
- package/dist/esm/Channels.d.ts +170 -0
- package/dist/esm/Channels.d.ts.map +1 -0
- package/dist/esm/Channels.js +312 -0
- package/dist/esm/Channels.js.map +1 -0
- package/dist/esm/Control.d.ts +202 -0
- package/dist/esm/Control.d.ts.map +1 -0
- package/dist/esm/Control.js +42 -0
- package/dist/esm/Control.js.map +1 -0
- package/dist/esm/ControlClient.d.ts +52 -0
- package/dist/esm/ControlClient.d.ts.map +1 -0
- package/dist/esm/ControlClient.js +217 -0
- package/dist/esm/ControlClient.js.map +1 -0
- package/dist/esm/ControlError.d.ts +318 -0
- package/dist/esm/ControlError.d.ts.map +1 -0
- package/dist/esm/ControlError.js +359 -0
- package/dist/esm/ControlError.js.map +1 -0
- package/dist/esm/ControlExecutor.d.ts +372 -0
- package/dist/esm/ControlExecutor.d.ts.map +1 -0
- package/dist/esm/ControlExecutor.js +212 -0
- package/dist/esm/ControlExecutor.js.map +1 -0
- package/dist/esm/ControlFacts.d.ts +454 -0
- package/dist/esm/ControlFacts.d.ts.map +1 -0
- package/dist/esm/ControlFacts.js +324 -0
- package/dist/esm/ControlFacts.js.map +1 -0
- package/dist/esm/ControlLive.d.ts +23 -0
- package/dist/esm/ControlLive.d.ts.map +1 -0
- package/dist/esm/ControlLive.js +1589 -0
- package/dist/esm/ControlLive.js.map +1 -0
- package/dist/esm/ControlRpcs.d.ts +1204 -0
- package/dist/esm/ControlRpcs.d.ts.map +1 -0
- package/dist/esm/ControlRpcs.js +299 -0
- package/dist/esm/ControlRpcs.js.map +1 -0
- package/dist/esm/ControlRuntime.d.ts +635 -0
- package/dist/esm/ControlRuntime.d.ts.map +1 -0
- package/dist/esm/ControlRuntime.js +808 -0
- package/dist/esm/ControlRuntime.js.map +1 -0
- package/dist/esm/ControlSchema.d.ts +2642 -0
- package/dist/esm/ControlSchema.d.ts.map +1 -0
- package/dist/esm/ControlSchema.js +1030 -0
- package/dist/esm/ControlSchema.js.map +1 -0
- package/dist/esm/ControlServer.d.ts +51 -0
- package/dist/esm/ControlServer.d.ts.map +1 -0
- package/dist/esm/ControlServer.js +145 -0
- package/dist/esm/ControlServer.js.map +1 -0
- package/dist/esm/Credential.d.ts +136 -0
- package/dist/esm/Credential.d.ts.map +1 -0
- package/dist/esm/Credential.js +190 -0
- package/dist/esm/Credential.js.map +1 -0
- package/dist/esm/CredentialCipher.d.ts +90 -0
- package/dist/esm/CredentialCipher.d.ts.map +1 -0
- package/dist/esm/CredentialCipher.js +56 -0
- package/dist/esm/CredentialCipher.js.map +1 -0
- package/dist/esm/CredentialStore.d.ts +97 -0
- package/dist/esm/CredentialStore.d.ts.map +1 -0
- package/dist/esm/CredentialStore.js +101 -0
- package/dist/esm/CredentialStore.js.map +1 -0
- package/dist/esm/DispatchReader.d.ts +112 -0
- package/dist/esm/DispatchReader.d.ts.map +1 -0
- package/dist/esm/DispatchReader.js +76 -0
- package/dist/esm/DispatchReader.js.map +1 -0
- package/dist/esm/Health.d.ts +333 -0
- package/dist/esm/Health.d.ts.map +1 -0
- package/dist/esm/Health.js +400 -0
- package/dist/esm/Health.js.map +1 -0
- package/dist/esm/JevSessionChecker.d.ts +57 -0
- package/dist/esm/JevSessionChecker.d.ts.map +1 -0
- package/dist/esm/JevSessionChecker.js +108 -0
- package/dist/esm/JevSessionChecker.js.map +1 -0
- package/dist/esm/Lineage.d.ts +131 -0
- package/dist/esm/Lineage.d.ts.map +1 -0
- package/dist/esm/Lineage.js +174 -0
- package/dist/esm/Lineage.js.map +1 -0
- package/dist/esm/Migrations.d.ts +34 -0
- package/dist/esm/Migrations.d.ts.map +1 -0
- package/dist/esm/Migrations.js +53 -0
- package/dist/esm/Migrations.js.map +1 -0
- package/dist/esm/Monitor.d.ts +282 -0
- package/dist/esm/Monitor.d.ts.map +1 -0
- package/dist/esm/Monitor.js +415 -0
- package/dist/esm/Monitor.js.map +1 -0
- package/dist/esm/ScopedToken.d.ts +193 -0
- package/dist/esm/ScopedToken.d.ts.map +1 -0
- package/dist/esm/ScopedToken.js +224 -0
- package/dist/esm/ScopedToken.js.map +1 -0
- package/dist/esm/SqlControlRuntime.d.ts +161 -0
- package/dist/esm/SqlControlRuntime.d.ts.map +1 -0
- package/dist/esm/SqlControlRuntime.js +1756 -0
- package/dist/esm/SqlControlRuntime.js.map +1 -0
- package/dist/esm/SqlCredentialStore.d.ts +43 -0
- package/dist/esm/SqlCredentialStore.d.ts.map +1 -0
- package/dist/esm/SqlCredentialStore.js +97 -0
- package/dist/esm/SqlCredentialStore.js.map +1 -0
- package/dist/esm/Steering.d.ts +69 -0
- package/dist/esm/Steering.d.ts.map +1 -0
- package/dist/esm/Steering.js +89 -0
- package/dist/esm/Steering.js.map +1 -0
- package/dist/esm/SystemFlows.d.ts +223 -0
- package/dist/esm/SystemFlows.d.ts.map +1 -0
- package/dist/esm/SystemFlows.js +198 -0
- package/dist/esm/SystemFlows.js.map +1 -0
- package/dist/esm/WebCryptoCipher.d.ts +49 -0
- package/dist/esm/WebCryptoCipher.d.ts.map +1 -0
- package/dist/esm/WebCryptoCipher.js +123 -0
- package/dist/esm/WebCryptoCipher.js.map +1 -0
- package/dist/esm/WebhookChannel.d.ts +113 -0
- package/dist/esm/WebhookChannel.d.ts.map +1 -0
- package/dist/esm/WebhookChannel.js +109 -0
- package/dist/esm/WebhookChannel.js.map +1 -0
- package/dist/esm/index.d.ts +160 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +160 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/MutationBoundary.d.ts +27 -0
- package/dist/esm/internal/MutationBoundary.d.ts.map +1 -0
- package/dist/esm/internal/MutationBoundary.js +40 -0
- package/dist/esm/internal/MutationBoundary.js.map +1 -0
- package/dist/esm/internal/activeFibers.d.ts +12 -0
- package/dist/esm/internal/activeFibers.d.ts.map +1 -0
- package/dist/esm/internal/activeFibers.js +17 -0
- package/dist/esm/internal/activeFibers.js.map +1 -0
- package/dist/esm/internal/issues.d.ts +28 -0
- package/dist/esm/internal/issues.d.ts.map +1 -0
- package/dist/esm/internal/issues.js +35 -0
- package/dist/esm/internal/issues.js.map +1 -0
- package/dist/esm/internal/planning.d.ts +347 -0
- package/dist/esm/internal/planning.d.ts.map +1 -0
- package/dist/esm/internal/planning.js +199 -0
- package/dist/esm/internal/planning.js.map +1 -0
- package/dist/esm/internal/sqlSchemaErrors.d.ts +18 -0
- package/dist/esm/internal/sqlSchemaErrors.d.ts.map +1 -0
- package/dist/esm/internal/sqlSchemaErrors.js +38 -0
- package/dist/esm/internal/sqlSchemaErrors.js.map +1 -0
- package/dist/esm/migrations/0001_control_tables.d.ts +18 -0
- package/dist/esm/migrations/0001_control_tables.d.ts.map +1 -0
- package/dist/esm/migrations/0001_control_tables.js +96 -0
- package/dist/esm/migrations/0001_control_tables.js.map +1 -0
- package/dist/esm/migrations/0002_run_keys.d.ts +15 -0
- package/dist/esm/migrations/0002_run_keys.d.ts.map +1 -0
- package/dist/esm/migrations/0002_run_keys.js +22 -0
- package/dist/esm/migrations/0002_run_keys.js.map +1 -0
- package/dist/esm/migrations/0003_signal_commands.d.ts +13 -0
- package/dist/esm/migrations/0003_signal_commands.d.ts.map +1 -0
- package/dist/esm/migrations/0003_signal_commands.js +26 -0
- package/dist/esm/migrations/0003_signal_commands.js.map +1 -0
- package/dist/esm/migrations/0004_approval_decisions.d.ts +13 -0
- package/dist/esm/migrations/0004_approval_decisions.d.ts.map +1 -0
- package/dist/esm/migrations/0004_approval_decisions.js +25 -0
- package/dist/esm/migrations/0004_approval_decisions.js.map +1 -0
- package/dist/esm/migrations/0005_signal_principals.d.ts +18 -0
- package/dist/esm/migrations/0005_signal_principals.d.ts.map +1 -0
- package/dist/esm/migrations/0005_signal_principals.js +27 -0
- package/dist/esm/migrations/0005_signal_principals.js.map +1 -0
- package/dist/esm/migrations/0006_run_principals.d.ts +18 -0
- package/dist/esm/migrations/0006_run_principals.d.ts.map +1 -0
- package/dist/esm/migrations/0006_run_principals.js +30 -0
- package/dist/esm/migrations/0006_run_principals.js.map +1 -0
- package/dist/esm/migrations/0007_resume_consent.d.ts +18 -0
- package/dist/esm/migrations/0007_resume_consent.d.ts.map +1 -0
- package/dist/esm/migrations/0007_resume_consent.js +27 -0
- package/dist/esm/migrations/0007_resume_consent.js.map +1 -0
- package/dist/esm/test/TestControl.d.ts +19 -0
- package/dist/esm/test/TestControl.d.ts.map +1 -0
- package/dist/esm/test/TestControl.js +30 -0
- package/dist/esm/test/TestControl.js.map +1 -0
- package/docs/README.md +189 -0
- package/docs/api.md +982 -0
- package/docs/concepts/authority.md +109 -0
- package/docs/concepts/cancellation.md +129 -0
- package/docs/concepts/lineage.md +132 -0
- package/docs/concepts/ownership.md +139 -0
- package/docs/concepts/projections.md +203 -0
- package/docs/concepts/receipts.md +128 -0
- package/docs/guides/approvals.md +284 -0
- package/docs/guides/cancel-and-resume.md +162 -0
- package/docs/guides/durable-storage.md +147 -0
- package/docs/guides/implement-an-executor.md +173 -0
- package/docs/guides/ingest-a-webhook.md +177 -0
- package/docs/guides/list-runs.md +160 -0
- package/docs/guides/monitor-runs.md +176 -0
- package/docs/guides/observe-health.md +147 -0
- package/docs/guides/postgres-tests.md +7 -0
- package/docs/guides/serve-over-rpc.md +220 -0
- package/docs/guides/signal-a-run.md +53 -0
- package/docs/guides/steer-a-run.md +138 -0
- package/docs/guides/store-credentials.md +164 -0
- package/docs/guides/testing.md +139 -0
- package/docs/guides/watch-a-run.md +154 -0
- package/docs/installation.md +106 -0
- package/docs/quickstart.md +163 -0
- package/docs/troubleshooting.md +208 -0
- package/package.json +405 -3
- package/src/ApprovalAuthority.ts +114 -0
- package/src/Cancellation.ts +172 -0
- package/src/Channels.ts +493 -0
- package/src/Control.ts +337 -0
- package/src/ControlClient.ts +319 -0
- package/src/ControlError.ts +378 -0
- package/src/ControlExecutor.ts +490 -0
- package/src/ControlFacts.ts +383 -0
- package/src/ControlLive.ts +2127 -0
- package/src/ControlRpcs.ts +443 -0
- package/src/ControlRuntime.ts +1601 -0
- package/src/ControlSchema.ts +1380 -0
- package/src/ControlServer.ts +182 -0
- package/src/Credential.ts +310 -0
- package/src/CredentialCipher.ts +110 -0
- package/src/CredentialStore.ts +152 -0
- package/src/DispatchReader.ts +122 -0
- package/src/Health.ts +591 -0
- package/src/JevSessionChecker.ts +127 -0
- package/src/Lineage.ts +203 -0
- package/src/Migrations.ts +56 -0
- package/src/Monitor.ts +600 -0
- package/src/ScopedToken.ts +306 -0
- package/src/SqlControlRuntime.ts +2478 -0
- package/src/SqlCredentialStore.ts +148 -0
- package/src/Steering.ts +96 -0
- package/src/SystemFlows.ts +225 -0
- package/src/WebCryptoCipher.ts +169 -0
- package/src/WebhookChannel.ts +166 -0
- package/src/index.ts +188 -0
- package/src/internal/MutationBoundary.ts +46 -0
- package/src/internal/activeFibers.ts +22 -0
- package/src/internal/issues.ts +40 -0
- package/src/internal/planning.ts +262 -0
- package/src/internal/sqlSchemaErrors.ts +37 -0
- package/src/migrations/0001_control_tables.ts +99 -0
- package/src/migrations/0002_run_keys.ts +23 -0
- package/src/migrations/0003_signal_commands.ts +27 -0
- package/src/migrations/0004_approval_decisions.ts +25 -0
- package/src/migrations/0005_signal_principals.ts +27 -0
- package/src/migrations/0006_run_principals.ts +31 -0
- package/src/migrations/0007_resume_consent.ts +28 -0
- package/src/test/TestControl.ts +47 -0
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema-backed RPC projection of the control service.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.1.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { NotificationError } from "@smthrs/notifications/NotificationQueue"
|
|
8
|
+
import { Context, Effect, Layer, Schema, SchemaTransformation } from "effect"
|
|
9
|
+
import { Rpc, RpcGroup, RpcMiddleware } from "effect/unstable/rpc"
|
|
10
|
+
import {
|
|
11
|
+
AlreadyResolved,
|
|
12
|
+
ClaimLost,
|
|
13
|
+
CodeDrift,
|
|
14
|
+
ControlErrorSchema,
|
|
15
|
+
EnvelopeMismatch,
|
|
16
|
+
FlowNotFound,
|
|
17
|
+
InvalidInput,
|
|
18
|
+
LaunchFailed,
|
|
19
|
+
NoMatchingWait,
|
|
20
|
+
PersistenceError,
|
|
21
|
+
PlanDenied,
|
|
22
|
+
PlanDigestMismatch,
|
|
23
|
+
PlanNotFound,
|
|
24
|
+
RunNotFound,
|
|
25
|
+
TransportError,
|
|
26
|
+
Unauthorized,
|
|
27
|
+
Unavailable
|
|
28
|
+
} from "./ControlError.ts"
|
|
29
|
+
import {
|
|
30
|
+
ApprovalInputSchema,
|
|
31
|
+
CancelInputSchema,
|
|
32
|
+
ControlEvent,
|
|
33
|
+
ListRequest,
|
|
34
|
+
ListResponse,
|
|
35
|
+
PlanCard,
|
|
36
|
+
PlanInputSchema,
|
|
37
|
+
type Principal,
|
|
38
|
+
Receipt,
|
|
39
|
+
ResumeInputSchema,
|
|
40
|
+
RunInputSchema,
|
|
41
|
+
SignalInputSchema,
|
|
42
|
+
SteerInputSchema,
|
|
43
|
+
WatchFilter
|
|
44
|
+
} from "./ControlSchema.ts"
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Authenticated principal made available to control RPC handlers.
|
|
48
|
+
*
|
|
49
|
+
* @category services
|
|
50
|
+
* @since 0.1.0
|
|
51
|
+
*/
|
|
52
|
+
export class ControlPrincipal extends Context.Service<ControlPrincipal, typeof Principal.Type>()(
|
|
53
|
+
"/control/ControlPrincipal"
|
|
54
|
+
) {}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Middleware boundary that authenticates control RPC requests.
|
|
58
|
+
*
|
|
59
|
+
* @category middleware
|
|
60
|
+
* @since 0.1.0
|
|
61
|
+
*/
|
|
62
|
+
export class ControlAuth extends RpcMiddleware.Service<ControlAuth, {
|
|
63
|
+
provides: ControlPrincipal
|
|
64
|
+
}>()("/control/ControlAuth", { error: Unauthorized }) {}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Which authenticated principals read every run.
|
|
68
|
+
*
|
|
69
|
+
* `List` and `Watch` answer a principal this returns `true` for with every
|
|
70
|
+
* run: that principal is an operator. Every other principal reads only the
|
|
71
|
+
* runs it launched (`RunSummary.launchedBy`) and, from `Watch`, only their
|
|
72
|
+
* events. The authentication layer decides, because it is what knows which
|
|
73
|
+
* identities it can stamp: `layerBearerAuth` and `layerNoopAuth` stamp one
|
|
74
|
+
* principal and make it the operator, and `layerAuth` takes the rule as an
|
|
75
|
+
* option. Where nothing provides one, no principal is an operator.
|
|
76
|
+
*
|
|
77
|
+
* @category services
|
|
78
|
+
* @since 1.0.0
|
|
79
|
+
*/
|
|
80
|
+
export const RunVisibility = Context.Reference<{
|
|
81
|
+
readonly seesAllRuns: (principal: typeof Principal.Type) => boolean
|
|
82
|
+
}>("/control/RunVisibility", { defaultValue: () => ({ seesAllRuns: () => false }) })
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The sentence a client reads when a control handler dies.
|
|
86
|
+
*
|
|
87
|
+
* @category defects
|
|
88
|
+
* @since 1.0.0
|
|
89
|
+
*/
|
|
90
|
+
export const defectMessage = "Something went wrong on our side. Not your fault."
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Wire schema for a control RPC defect: an untyped failure that no procedure
|
|
94
|
+
* declares.
|
|
95
|
+
*
|
|
96
|
+
* Encoding replaces a defect value (an `Error`, a failure an `orDie` turned
|
|
97
|
+
* into a defect, any non-string value) with `{ name: "Error", message }`
|
|
98
|
+
* carrying {@link defectMessage}, so a driver message, path, or stack never
|
|
99
|
+
* reaches a client. The server logs the raw defect. A string passes unchanged:
|
|
100
|
+
* the RPC server's own request-decoding sentence, which describes the caller's
|
|
101
|
+
* payload, is one, and so is an author-written `Effect.die` sentence.
|
|
102
|
+
*
|
|
103
|
+
* Decoding is Effect's default `Schema.Defect()` decoding, so a client reads
|
|
104
|
+
* this shape and an older server's shape alike, and an older client reads this
|
|
105
|
+
* shape as an `Error`.
|
|
106
|
+
*
|
|
107
|
+
* @category defects
|
|
108
|
+
* @since 1.0.0
|
|
109
|
+
*/
|
|
110
|
+
export const ControlDefect = Schema.Json.pipe(Schema.decodeTo(
|
|
111
|
+
Schema.Unknown,
|
|
112
|
+
SchemaTransformation.transform({
|
|
113
|
+
decode: Schema.decodeSync(Schema.Defect()),
|
|
114
|
+
encode: (defect): Schema.Json => typeof defect === "string" ? defect : { name: "Error", message: defectMessage }
|
|
115
|
+
})
|
|
116
|
+
))
|
|
117
|
+
|
|
118
|
+
const mutationErrors = Schema.Union([
|
|
119
|
+
RunNotFound,
|
|
120
|
+
ClaimLost,
|
|
121
|
+
InvalidInput,
|
|
122
|
+
PersistenceError,
|
|
123
|
+
Unavailable,
|
|
124
|
+
TransportError,
|
|
125
|
+
Unauthorized
|
|
126
|
+
])
|
|
127
|
+
|
|
128
|
+
const resumeErrors = Schema.Union([
|
|
129
|
+
RunNotFound,
|
|
130
|
+
ClaimLost,
|
|
131
|
+
CodeDrift,
|
|
132
|
+
InvalidInput,
|
|
133
|
+
PersistenceError,
|
|
134
|
+
Unavailable,
|
|
135
|
+
TransportError,
|
|
136
|
+
Unauthorized
|
|
137
|
+
])
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The ten remote procedures corresponding to `Control` operations.
|
|
141
|
+
*
|
|
142
|
+
* @category groups
|
|
143
|
+
* @since 0.1.0
|
|
144
|
+
*/
|
|
145
|
+
export const ControlRpcs = RpcGroup.make(
|
|
146
|
+
Rpc.make("Plan", {
|
|
147
|
+
defect: ControlDefect,
|
|
148
|
+
payload: PlanInputSchema,
|
|
149
|
+
success: PlanCard,
|
|
150
|
+
error: Schema.Union([FlowNotFound, InvalidInput, PersistenceError, Unavailable, TransportError, Unauthorized])
|
|
151
|
+
}),
|
|
152
|
+
Rpc.make("Run", {
|
|
153
|
+
defect: ControlDefect,
|
|
154
|
+
payload: RunInputSchema,
|
|
155
|
+
success: Receipt,
|
|
156
|
+
error: Schema.Union([
|
|
157
|
+
RunNotFound,
|
|
158
|
+
PlanNotFound,
|
|
159
|
+
PlanDenied,
|
|
160
|
+
PlanDigestMismatch,
|
|
161
|
+
EnvelopeMismatch,
|
|
162
|
+
ClaimLost,
|
|
163
|
+
CodeDrift,
|
|
164
|
+
InvalidInput,
|
|
165
|
+
LaunchFailed,
|
|
166
|
+
PersistenceError,
|
|
167
|
+
Unavailable,
|
|
168
|
+
TransportError,
|
|
169
|
+
Unauthorized
|
|
170
|
+
])
|
|
171
|
+
}),
|
|
172
|
+
Rpc.make("Approve", {
|
|
173
|
+
defect: ControlDefect,
|
|
174
|
+
payload: ApprovalInputSchema,
|
|
175
|
+
success: Receipt,
|
|
176
|
+
error: Schema.Union([
|
|
177
|
+
PlanDigestMismatch,
|
|
178
|
+
EnvelopeMismatch,
|
|
179
|
+
AlreadyResolved,
|
|
180
|
+
PlanNotFound,
|
|
181
|
+
RunNotFound,
|
|
182
|
+
CodeDrift,
|
|
183
|
+
InvalidInput,
|
|
184
|
+
Unauthorized,
|
|
185
|
+
PersistenceError,
|
|
186
|
+
Unavailable,
|
|
187
|
+
TransportError
|
|
188
|
+
])
|
|
189
|
+
}),
|
|
190
|
+
Rpc.make("Deny", {
|
|
191
|
+
defect: ControlDefect,
|
|
192
|
+
payload: ApprovalInputSchema,
|
|
193
|
+
success: Receipt,
|
|
194
|
+
error: Schema.Union([
|
|
195
|
+
PlanDigestMismatch,
|
|
196
|
+
EnvelopeMismatch,
|
|
197
|
+
AlreadyResolved,
|
|
198
|
+
PlanNotFound,
|
|
199
|
+
RunNotFound,
|
|
200
|
+
CodeDrift,
|
|
201
|
+
InvalidInput,
|
|
202
|
+
Unauthorized,
|
|
203
|
+
PersistenceError,
|
|
204
|
+
Unavailable,
|
|
205
|
+
TransportError
|
|
206
|
+
])
|
|
207
|
+
}),
|
|
208
|
+
Rpc.make("Steer", {
|
|
209
|
+
defect: ControlDefect,
|
|
210
|
+
payload: SteerInputSchema,
|
|
211
|
+
success: Receipt,
|
|
212
|
+
error: Schema.Union([
|
|
213
|
+
RunNotFound,
|
|
214
|
+
InvalidInput,
|
|
215
|
+
PersistenceError,
|
|
216
|
+
Unavailable,
|
|
217
|
+
TransportError,
|
|
218
|
+
Unauthorized,
|
|
219
|
+
NotificationError
|
|
220
|
+
])
|
|
221
|
+
}),
|
|
222
|
+
Rpc.make("Signal", {
|
|
223
|
+
defect: ControlDefect,
|
|
224
|
+
payload: SignalInputSchema,
|
|
225
|
+
success: Receipt,
|
|
226
|
+
error: Schema.Union([
|
|
227
|
+
RunNotFound,
|
|
228
|
+
NoMatchingWait,
|
|
229
|
+
InvalidInput,
|
|
230
|
+
PersistenceError,
|
|
231
|
+
Unavailable,
|
|
232
|
+
TransportError,
|
|
233
|
+
Unauthorized
|
|
234
|
+
])
|
|
235
|
+
}),
|
|
236
|
+
Rpc.make("Cancel", { defect: ControlDefect, payload: CancelInputSchema, success: Receipt, error: mutationErrors }),
|
|
237
|
+
Rpc.make("Resume", {
|
|
238
|
+
defect: ControlDefect,
|
|
239
|
+
payload: ResumeInputSchema,
|
|
240
|
+
success: Receipt,
|
|
241
|
+
error: resumeErrors
|
|
242
|
+
}),
|
|
243
|
+
// `list` and `watch` carry the whole `ControlError` union in their contract,
|
|
244
|
+
// so they name it once rather than restating its members. Two hand-copied
|
|
245
|
+
// lists is how `CredentialConflict` came to be a control error the union did
|
|
246
|
+
// not admit.
|
|
247
|
+
Rpc.make("List", {
|
|
248
|
+
defect: ControlDefect,
|
|
249
|
+
payload: ListRequest,
|
|
250
|
+
success: ListResponse,
|
|
251
|
+
error: ControlErrorSchema
|
|
252
|
+
}),
|
|
253
|
+
Rpc.make("Watch", {
|
|
254
|
+
defect: ControlDefect,
|
|
255
|
+
payload: WatchFilter,
|
|
256
|
+
success: ControlEvent,
|
|
257
|
+
error: ControlErrorSchema,
|
|
258
|
+
stream: true
|
|
259
|
+
})
|
|
260
|
+
).middleware(ControlAuth)
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* The call a boundary is authenticating, when it knows one: the procedure's
|
|
264
|
+
* tag and the payload it was sent. An edge authenticating a socket upgrade
|
|
265
|
+
* knows no call and passes none.
|
|
266
|
+
*
|
|
267
|
+
* @category models
|
|
268
|
+
* @since 1.0.0
|
|
269
|
+
*/
|
|
270
|
+
export interface Call {
|
|
271
|
+
readonly rpc: string
|
|
272
|
+
readonly payload: unknown
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Header authenticator used by the control RPC boundary.
|
|
277
|
+
*
|
|
278
|
+
* `call` is present for an in-band RPC frame and absent at a transport edge.
|
|
279
|
+
* An authenticator that grants everything ignores it; one that grants a
|
|
280
|
+
* scope reads it, and admits an edge on the credential alone.
|
|
281
|
+
*
|
|
282
|
+
* @category models
|
|
283
|
+
* @since 0.1.0
|
|
284
|
+
*/
|
|
285
|
+
export interface Authenticator {
|
|
286
|
+
readonly authenticate: (
|
|
287
|
+
headers: Readonly<Record<string, string>>,
|
|
288
|
+
call?: Call | undefined
|
|
289
|
+
) => Effect.Effect<typeof Principal.Type, Unauthorized>
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Configuration for the single-token bearer authenticator.
|
|
294
|
+
*
|
|
295
|
+
* Every request carrying the configured token receives the same principal.
|
|
296
|
+
* This is the intentionally small alpha trust boundary, not a per-user
|
|
297
|
+
* authorization system.
|
|
298
|
+
*
|
|
299
|
+
* @category models
|
|
300
|
+
* @since 0.1.0
|
|
301
|
+
*/
|
|
302
|
+
export interface BearerAuthOptions {
|
|
303
|
+
readonly token: string
|
|
304
|
+
readonly principal: Omit<typeof Principal.Type, "stampedAt">
|
|
305
|
+
readonly now?: (() => number) | undefined
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const authorizationHeader = (headers: Readonly<Record<string, string>>): string | undefined => {
|
|
309
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
310
|
+
if (name.toLowerCase() === "authorization") return value
|
|
311
|
+
}
|
|
312
|
+
return undefined
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* The bearer credential a request carries, or `undefined` when its
|
|
317
|
+
* `Authorization` header is absent or is not a well-formed bearer scheme.
|
|
318
|
+
*
|
|
319
|
+
* @category getters
|
|
320
|
+
* @since 1.0.0
|
|
321
|
+
*/
|
|
322
|
+
export const bearerCredential = (headers: Readonly<Record<string, string>>): string | undefined => {
|
|
323
|
+
const authorization = authorizationHeader(headers)
|
|
324
|
+
if (authorization === undefined) return undefined
|
|
325
|
+
const match = /^Bearer[\t ]+([^\t ]+)$/i.exec(authorization)
|
|
326
|
+
return match?.[1]
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const encoder = new TextEncoder()
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Compares UTF-8 credentials without returning early for a secret-dependent
|
|
333
|
+
* byte or length difference.
|
|
334
|
+
*/
|
|
335
|
+
const constantTimeTokenEqual = (expected: string, actual: string): boolean => {
|
|
336
|
+
const expectedBytes = encoder.encode(expected)
|
|
337
|
+
const actualBytes = encoder.encode(actual)
|
|
338
|
+
const length = Math.max(expectedBytes.length, actualBytes.length)
|
|
339
|
+
let difference = expectedBytes.length ^ actualBytes.length
|
|
340
|
+
|
|
341
|
+
for (let index = 0; index < length; index++) {
|
|
342
|
+
difference |= (expectedBytes[index] ?? 0) ^ (actualBytes[index] ?? 0)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return difference === 0
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Authenticates one shared bearer token and stamps its server-owned principal.
|
|
350
|
+
* Missing, malformed, empty, and incorrect credentials all fail closed with
|
|
351
|
+
* the same `Unauthorized` response.
|
|
352
|
+
*
|
|
353
|
+
* @category constructors
|
|
354
|
+
* @since 0.1.0
|
|
355
|
+
*/
|
|
356
|
+
export const bearerAuthenticator = (options: BearerAuthOptions): Authenticator => ({
|
|
357
|
+
authenticate: (headers) => {
|
|
358
|
+
const credential = bearerCredential(headers)
|
|
359
|
+
return options.token.length > 0 && credential !== undefined && constantTimeTokenEqual(options.token, credential)
|
|
360
|
+
? Effect.succeed({
|
|
361
|
+
...options.principal,
|
|
362
|
+
stampedAt: options.now?.() ?? Date.now()
|
|
363
|
+
})
|
|
364
|
+
: Effect.fail(new Unauthorized({ message: "A valid bearer credential is required" }))
|
|
365
|
+
}
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* The first authenticator to accept a request answers for all of them. Each
|
|
370
|
+
* is asked in order, and a request none accepts fails with the last refusal,
|
|
371
|
+
* or with the plain `Unauthorized` when there is nothing to ask.
|
|
372
|
+
*
|
|
373
|
+
* @category constructors
|
|
374
|
+
* @since 1.0.0
|
|
375
|
+
*/
|
|
376
|
+
export const anyAuthenticator = (authenticators: ReadonlyArray<Authenticator>): Authenticator => ({
|
|
377
|
+
authenticate: (headers, call) =>
|
|
378
|
+
authenticators.reduce<Effect.Effect<typeof Principal.Type, Unauthorized>>(
|
|
379
|
+
(attempt, authenticator) =>
|
|
380
|
+
Effect.catchTag(attempt, "/control/Unauthorized", () => authenticator.authenticate(headers, call)),
|
|
381
|
+
Effect.fail(new Unauthorized({ message: "A valid bearer credential is required" }))
|
|
382
|
+
)
|
|
383
|
+
})
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Options for {@link layerAuth}.
|
|
387
|
+
*
|
|
388
|
+
* @category models
|
|
389
|
+
* @since 1.0.0
|
|
390
|
+
*/
|
|
391
|
+
export interface AuthOptions {
|
|
392
|
+
/**
|
|
393
|
+
* The operators: the principals `List` and `Watch` show every run. Omitted,
|
|
394
|
+
* every principal reads only the runs it launched. See {@link RunVisibility}.
|
|
395
|
+
*/
|
|
396
|
+
readonly seesAllRuns?: ((principal: typeof Principal.Type) => boolean) | undefined
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Provides `ControlAuth` from a transport-header authenticator, telling it
|
|
401
|
+
* which procedure and payload each frame carries. Each authenticated call
|
|
402
|
+
* also receives the {@link RunVisibility} rule for the principal it stamps.
|
|
403
|
+
*
|
|
404
|
+
* @category layers
|
|
405
|
+
* @since 0.1.0
|
|
406
|
+
*/
|
|
407
|
+
export const layerAuth = (authenticator: Authenticator, options: AuthOptions = {}) => {
|
|
408
|
+
const visibility = { seesAllRuns: options.seesAllRuns ?? (() => false) }
|
|
409
|
+
return Layer.succeed(
|
|
410
|
+
ControlAuth,
|
|
411
|
+
(effect, call) =>
|
|
412
|
+
Effect.flatMap(
|
|
413
|
+
authenticator.authenticate(call.headers, { rpc: call.rpc._tag, payload: call.payload }),
|
|
414
|
+
(principal) =>
|
|
415
|
+
effect.pipe(
|
|
416
|
+
Effect.provideService(ControlPrincipal, principal),
|
|
417
|
+
Effect.provideService(RunVisibility, visibility)
|
|
418
|
+
)
|
|
419
|
+
)
|
|
420
|
+
)
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Provides `ControlAuth` using one shared bearer token. Its one principal is
|
|
425
|
+
* the operator and reads every run.
|
|
426
|
+
*
|
|
427
|
+
* @category layers
|
|
428
|
+
* @since 0.1.0
|
|
429
|
+
*/
|
|
430
|
+
export const layerBearerAuth = (options: BearerAuthOptions) =>
|
|
431
|
+
layerAuth(bearerAuthenticator(options), { seesAllRuns: () => true })
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Permissive authentication middleware for tests and trusted in-process use.
|
|
435
|
+
*
|
|
436
|
+
* @category layers
|
|
437
|
+
* @since 0.1.0
|
|
438
|
+
*/
|
|
439
|
+
export const layerNoopAuth = (principal: typeof Principal.Type = {
|
|
440
|
+
id: "test-principal",
|
|
441
|
+
kind: "test",
|
|
442
|
+
stampedAt: 0
|
|
443
|
+
}) => layerAuth({ authenticate: () => Effect.succeed(principal) }, { seesAllRuns: () => true })
|