@smthrs/control 0.0.0-stage → 1.0.0-rc.3
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 +1280 -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 +740 -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 +1521 -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 +1585 -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 +807 -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 +5 -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 +2113 -0
- package/src/ControlRpcs.ts +443 -0
- package/src/ControlRuntime.ts +1597 -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 +2476 -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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# @smthrs/control
|
|
2
|
+
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `ControlExecutor.Service.requestComplete` optionally closes a retained run
|
|
8
|
+
after its last native module completes, through the host executor.
|
|
9
|
+
|
|
10
|
+
- `PlanInput.budget` can override budget fields, including the optional
|
|
11
|
+
`onExceeded` policy. Resume accepts `allowCodeDrift`; run and approval
|
|
12
|
+
operations can also fail with `CodeDrift`. Custom runtime implementations
|
|
13
|
+
must provide `codeDrift`; SQL runtime options accept `currentFlows`
|
|
14
|
+
for checking the current catalog (#1807, #1843).
|
|
15
|
+
|
|
16
|
+
- A run records its flow's `executionDigest` and the host's `engineVersion`
|
|
17
|
+
(`SqlControlRuntime` and memory option `engineVersion`) on `RunSummary`.
|
|
18
|
+
`Control.resume` refuses a run whose flow's digest changed with `CodeDrift`
|
|
19
|
+
before claiming it, unless `allowCodeDrift` is set.
|
|
20
|
+
|
|
21
|
+
- `Health.makeRegistry` takes an optional third argument, `evaluator`: the
|
|
22
|
+
judge the registered `jev.session` checker asks.
|
|
23
|
+
|
|
24
|
+
- `SqlControlRuntime` takes `isAlive`: with it, `resume` takes over a running
|
|
25
|
+
run whose owner is gone (a host killed mid-run) once the dead owner's lease
|
|
26
|
+
has expired, instead of answering `ClaimLost`; the run store verifies the
|
|
27
|
+
expired lease.
|
|
28
|
+
|
|
29
|
+
- `ControlExecutor.makeObserving` wraps an executor for a host that observes
|
|
30
|
+
runs and drives none: `readExecution`, `requestCancel`, `deliverSignal` and
|
|
31
|
+
`settleCancelledPark` pass through, and `launch` and `resumeRun` die. A host
|
|
32
|
+
with no completion judge composes one, so it can list and diagnose runs
|
|
33
|
+
without being able to admit one it could never judge.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- **Breaking:** `JevSessionChecker` asks the host's `Evaluator` instead of
|
|
38
|
+
calling the Vercel AI Gateway itself. `jevEvaluationUrl`, `jevModelId` and
|
|
39
|
+
the `env`, `fetch` and `url` options are removed; `evaluator` replaces them.
|
|
40
|
+
Without an evaluator the probe fails with reason `unconfigured`.
|
|
41
|
+
`jevRequestTimeoutMs` is now 45000 (was 1500) and `jevProbeTimeoutMs` 50000
|
|
42
|
+
(was 2500).
|
|
43
|
+
- A journal read that fails during `watch` answers `PersistenceError` with
|
|
44
|
+
operation `watch` and the journal's error as its `cause`. It used to answer
|
|
45
|
+
`Unavailable`, which reads as a missing feature. A closed journal still
|
|
46
|
+
answers `Unavailable`.
|
|
47
|
+
- `WebCryptoCipher.open` answers `PersistenceError` with operation
|
|
48
|
+
`credential.open` when a record does not open, naming a malformed nonce or a
|
|
49
|
+
failed authentication (a different key, changed metadata, or tampered
|
|
50
|
+
ciphertext), and logs the reason. `WebCryptoCipher.make` refuses a key that
|
|
51
|
+
is not 32 base64-encoded bytes with `InvalidInput`. Both used to answer
|
|
52
|
+
`Unavailable`, which is now kept for a host without Web Crypto.
|
|
53
|
+
- Breaking: `ApprovalAuthority.local` no longer delegates the in-memory test
|
|
54
|
+
identity `memory`/`test`. A caller naming kind `test` held full approval
|
|
55
|
+
authority under the production default. `ControlRuntime.layerMemory`
|
|
56
|
+
delegates that identity in its own default policy.
|
|
57
|
+
- Removed the 195 internal `@slop` review markers from `src` and the published
|
|
58
|
+
declarations. `test/ReviewMarkers.test.ts` keeps them out.
|
|
59
|
+
- Breaking: approval decisions require an independent `ApprovalAuthority` host
|
|
60
|
+
policy, checked before reads/replay and again at resolution. Custom agent,
|
|
61
|
+
gateway, and operator identities need explicit delegation; attribution and
|
|
62
|
+
authentication alone do not authorize approval. RPC approval errors include
|
|
63
|
+
`Unauthorized`. Policy storage failure leaves the gate closed.
|
|
64
|
+
|
|
65
|
+
- Breaking: approval tokens now expose `Pending`, `Approved`, or `Denied`
|
|
66
|
+
instead of `resolved`. Terminal decisions retain their principal and time;
|
|
67
|
+
approvals also retain scope. `requireApproved` fails closed on pending or
|
|
68
|
+
denied requests. The documented gate no longer proceeds after denial or
|
|
69
|
+
mistakes a storage error for approval.
|
|
70
|
+
- Migration 6004 stores the decision atomically with resolution. Legacy pending
|
|
71
|
+
requests remain pending; old terminal requests that erased their decision are
|
|
72
|
+
refused on recovery. Preserve old evidence and start a new run/request. This
|
|
73
|
+
does not migrate old executable identities or cached gate results.
|
|
74
|
+
|
|
75
|
+
### Fixed
|
|
76
|
+
|
|
77
|
+
- Durable sequence allocation rejects missing, nonpositive, or unsafe numeric
|
|
78
|
+
readbacks inside its transaction, so storage faults cannot create zero or
|
|
79
|
+
rounded plan, run, or resume identities.
|
|
80
|
+
- Optional SQL table reads fall back only when the driver names that exact
|
|
81
|
+
missing relation. A broken view referencing a similarly named missing table
|
|
82
|
+
now reports a persistence failure instead of silently dropping run ancestry.
|
|
83
|
+
|
|
84
|
+
- Fixed the CommonJS build of the migration set. `migrations/0001_control_tables`
|
|
85
|
+
now exports `initial` as a named binding and every importer reads it by name,
|
|
86
|
+
because esbuild's Node interop for a default import of a sibling module
|
|
87
|
+
resolved to the whole exports object instead of the Effect, so
|
|
88
|
+
`require("@smthrs/control")` failed at load with
|
|
89
|
+
`initial.pipe is not a function`.
|
|
90
|
+
|
|
91
|
+
## [1.0.0-rc.0] - 2026-09-01
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
|
|
95
|
+
- Added `ControlExecutor`, the port that hands launches, cancellations,
|
|
96
|
+
signals, and resumes to a real run executor, so `ControlLive` drives an
|
|
97
|
+
engine instead of describing one.
|
|
98
|
+
- Added `SqlControlRuntime`, the durable `ControlRuntime` over `@smthrs/journal`
|
|
99
|
+
and the fenced `@smthrs/run-store`, and the credential subsystem behind it
|
|
100
|
+
(`Credential`, `CredentialCipher`, `CredentialStore`, `SqlCredentialStore`,
|
|
101
|
+
`WebCryptoCipher`).
|
|
102
|
+
- Added durable resume delegation: a decided run's restart is recorded for the
|
|
103
|
+
host that owns it and taken up on that host's next poll, rather than claimed
|
|
104
|
+
by a control plane with no executor (triage B-15).
|
|
105
|
+
- Added cancellation attribution: `control.run.cancel-requested` carries the
|
|
106
|
+
authenticated principal and the operator's stated reason, and
|
|
107
|
+
`Cancellation.attribute` folds a run's own evidence and its ancestors' into
|
|
108
|
+
`RunSummary.cancellation`.
|
|
109
|
+
- Added `NoMatchingWait`, so a signal naming a wait point no run has open is
|
|
110
|
+
refused where it arrives instead of being recorded as delivered.
|
|
111
|
+
- Added `Monitor`, which classifies run health from durable evidence and
|
|
112
|
+
applies only the remedies `autoHeal` names.
|
|
113
|
+
- Added `Lineage` and `Steering` projections, so a client reading the journal
|
|
114
|
+
directly reaches the same conclusions the server does.
|
|
115
|
+
- Added `ControlSchema.defaultPageSize`, `ControlSchema.maxPageSize`, and
|
|
116
|
+
`ControlSchema.PageLimit`, so a listing has a documented bound the wire
|
|
117
|
+
enforces.
|
|
118
|
+
- Added `ControlError.ControlErrorSchema` as the single membership list for the
|
|
119
|
+
`ControlError` union, and added `CredentialConflict` to it.
|
|
120
|
+
- Added `SystemFlows.plannable` and a `plannable` marker on every catalog entry,
|
|
121
|
+
so a verb the release policy removed cannot be planned as a flow.
|
|
122
|
+
- Added the namespaced `Migrations` module for every control and credential
|
|
123
|
+
table, while standalone adapters reuse the same idempotent schema source.
|
|
124
|
+
|
|
125
|
+
### Changed
|
|
126
|
+
|
|
127
|
+
- `Control.run({_tag: "Resume"})` is the same operation as `Control.resume`.
|
|
128
|
+
It used to be a second path that claimed without `scope: "launched"` (which
|
|
129
|
+
overwrote an engine-created run's continuation state), replayed a recorded
|
|
130
|
+
receipt for a run that had since settled, and journaled `control.run.resumed`,
|
|
131
|
+
which the agent bridge reads as an approval delegation.
|
|
132
|
+
- `Control.resume` records the authenticated principal and the stated reason on
|
|
133
|
+
`control.run.resume`, and the `Resume` RPC payload carries `reason` so a local
|
|
134
|
+
and a remote resume no longer differ.
|
|
135
|
+
- `Control.plan` journals `control.plan.created` only when it created a plan.
|
|
136
|
+
`ControlRuntime.plan` returns `{ card, created }` to say which happened.
|
|
137
|
+
- `Control.list` reads one run through `getRun` when `filters.runId` names one,
|
|
138
|
+
instead of projecting every row in the database.
|
|
139
|
+
- `Control.list` refuses `filters.principalId`. It was accepted and applied
|
|
140
|
+
nowhere, so a caller using it as a tenant restriction received every run.
|
|
141
|
+
- `Control.list` refuses a page size that cannot make progress and a cursor it
|
|
142
|
+
did not issue, and applies `defaultPageSize` when the caller names none. A
|
|
143
|
+
zero-sized page used to answer with a cursor a client loops on forever.
|
|
144
|
+
- `Control.steer` refuses a message whose `message.runId` disagrees with the
|
|
145
|
+
run the call names, and records the message's stated `createdAt` on
|
|
146
|
+
`control.steer.enqueued`.
|
|
147
|
+
- `Control.watch` refuses `afterSequence` without `runId`. Journal sequences are
|
|
148
|
+
partition-local, so one scalar cursor applied to every partition skipped
|
|
149
|
+
unseen entries in all of them but its own.
|
|
150
|
+
- Unscoped follow mode now subscribes before pinning one high-water mark per
|
|
151
|
+
partition, then joins the finite snapshot to the buffered tail at those
|
|
152
|
+
marks. The former 1,024-key cache could re-emit old overlap after eviction.
|
|
153
|
+
- A cancel that learns the engine row already settled reconciles the control row
|
|
154
|
+
onto the engine's own status instead of leaving it non-terminal forever.
|
|
155
|
+
- Mutations now snapshot at an inert, schema-decoded 4 MiB boundary before
|
|
156
|
+
their first wait. Durable identity is a fixed-size canonical SHA-256 digest
|
|
157
|
+
scoped to the authenticated actor's stable id and kind; accessors and
|
|
158
|
+
`toJSON` never participate, server timestamps do not split retries, and a
|
|
159
|
+
nested `principal` remains caller intent.
|
|
160
|
+
- `ControlClient` classifies a transport failure by what actually happened. A
|
|
161
|
+
request it could not encode, a response it could not decode, an unusable URL
|
|
162
|
+
and an HTTP 4xx are final; a connection it could not open and an HTTP 5xx are
|
|
163
|
+
retryable. Every failure used to be reported as retryable, carrying the
|
|
164
|
+
transport's own message, so a keyless call was retried after a refusal that
|
|
165
|
+
repeating could not fix. An interrupted call stays interrupted.
|
|
166
|
+
- `Monitor` records `control.monitor.healed` only for an `Accepted` or
|
|
167
|
+
`AlreadyApplied` receipt, stops on a `Terminal` one, and no longer resets its
|
|
168
|
+
stall evidence for a remedy that was refused.
|
|
169
|
+
- `SqlControlRuntime.listRuns` omits a row deleted between reading the id index
|
|
170
|
+
and reading the row, instead of collapsing the whole listing to `[]`.
|
|
171
|
+
- Separately constructed `SqlControlRuntime` instances now mint distinct valid
|
|
172
|
+
default owner identities, so one runtime cannot write through another's
|
|
173
|
+
process fence when a host omits an explicit owner.
|
|
174
|
+
- Channel ingestion snapshots caller-owned bytes and headers before
|
|
175
|
+
verification, and adapters declare the non-secret semantic headers included
|
|
176
|
+
in durable idempotency fingerprints.
|
|
177
|
+
- `SqlControlRuntime.make` is the only exported constructor; the duplicate
|
|
178
|
+
`make_` and the re-exported `FlowId` are gone.
|
|
179
|
+
- Approval tokens and bulk grants use the complete plan or node identity in
|
|
180
|
+
memory and SQL. The SQL storage format now records target kind, run, target
|
|
181
|
+
id, and the authenticated principal that resolved each token.
|
|
182
|
+
- Credential ciphertext authenticates a versioned canonical encoding of its
|
|
183
|
+
stored id, name, and credential version, so blob moves, renames, and version
|
|
184
|
+
rollbacks fail closed.
|
|
185
|
+
- The memory control runtime and credential store copy values at their storage
|
|
186
|
+
boundaries, matching SQL serialization when callers mutate inputs or results.
|
|
187
|
+
- Public control JSDoc points only to documentation paths present in this
|
|
188
|
+
repository.
|
|
189
|
+
|
|
190
|
+
### Removed
|
|
191
|
+
|
|
192
|
+
- Removed `Control.pause`. The frozen 1.0.0-rc.0 contract has no pause verb; an
|
|
193
|
+
operator park is written through
|
|
194
|
+
`ControlRuntime.writeStatus(runId, fence, "parked")`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 William Cory and the Smithers Flows contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,169 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @smthrs/control
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Release candidate scope, host requirements and compatibility review are defined in the [library support policy](https://github.com/smithersai/smithers/blob/main/RELEASE_SUPPORT.md).
|
|
4
|
+
|
|
5
|
+
This package declares `effect` as an exact
|
|
6
|
+
`4.0.0-rc.115` peer dependency. Keep the application on that version so
|
|
7
|
+
all Smithers packages share one Effect runtime.
|
|
8
|
+
|
|
9
|
+
**Documentation:** https://control.smithers.sh
|
|
10
|
+
|
|
11
|
+
Control services and RPC projections for flows. It defines the
|
|
12
|
+
transport-independent Control service, its runtime and execution ports, local
|
|
13
|
+
and RPC implementations, verified ingress channels, credentials, and the shared
|
|
14
|
+
wire schemas both halves decode.
|
|
15
|
+
|
|
16
|
+
Not on npm yet; see [Installation](https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/flow/docs/installation.md#use-the-libraries).
|
|
17
|
+
|
|
18
|
+
The package
|
|
19
|
+
requires Node.js 26.4.0 or later and ships as both ESM and CommonJS with
|
|
20
|
+
TypeScript declarations.
|
|
21
|
+
|
|
22
|
+
It imports no `node:*` module, so the same modules run in Node.js and in a
|
|
23
|
+
browser that supplies a SQL driver. That is a statement about the imports, not
|
|
24
|
+
a tested guarantee: verify your own bundle before you depend on it.
|
|
25
|
+
|
|
26
|
+
The `smthrs` command line, [`@smthrs/cli`](https://cli.smithers.sh), is a host
|
|
27
|
+
over this package: its verbs call the `Control` service defined here and
|
|
28
|
+
nothing else. Install the CLI to drive runs from a shell; install this package
|
|
29
|
+
to build a host of your own, such as a gateway, an MCP server, or a dashboard.
|
|
30
|
+
|
|
31
|
+
## Public API
|
|
32
|
+
|
|
33
|
+
The root entry point exports these namespaces; each is also importable from
|
|
34
|
+
`@smthrs/control/<Module>`. Every export of every namespace, with its
|
|
35
|
+
signature, is on the [API reference](https://control.smithers.sh/reference/api/).
|
|
36
|
+
|
|
37
|
+
| Namespace | What it is |
|
|
38
|
+
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
39
|
+
| `Control` | The service: `plan`, `run`, `approve`, `deny`, `steer`, `signal`, `cancel`, `resume`, `list`, `watch`. |
|
|
40
|
+
| `ControlSchema` | The serializable values both halves of the wire decode, and the RPC request schemas. |
|
|
41
|
+
| `ControlError` | Every stable failure, as classes and as one membership schema. |
|
|
42
|
+
| `ControlLive` | The in-process implementation over the runtime, the journal, the notification queue, and the registry. |
|
|
43
|
+
| `ControlRuntime` | The persistence port, plus `layerMemory`. |
|
|
44
|
+
| `SqlControlRuntime` | The durable persistence adapter over a SQL database and the fenced run store. |
|
|
45
|
+
| `ControlExecutor` | The execution port: launch, cancel, signal, resume, and the park settlement a cancel needs. |
|
|
46
|
+
| `DispatchReader` | The trigger read port: registered triggers and the fire ledger `list` pages; `layerNone` refuses. |
|
|
47
|
+
| `ControlRpcs`, `ControlServer`, `ControlClient` | The RPC contract, the HTTP and WebSocket mount, and the client projected back into `Control`. |
|
|
48
|
+
| `ScopedToken` | Scoped, expiring tokens minted under a bearer credential and verified with it. |
|
|
49
|
+
| `Lineage`, `Cancellation`, `Steering` | Pure projections: how a run came to exist, who cancelled it, and when a steer was delivered. |
|
|
50
|
+
| `Monitor` | Run health as a pure classification, and the beat loop that acts on it. |
|
|
51
|
+
| `Health` | Configurable Effect checks, bounded observation policies, provenance, and the shared status rollup. |
|
|
52
|
+
| `JevSessionChecker` | The registered `jev.session` checker: does this session's own output show it waiting on a person? |
|
|
53
|
+
| `Channels`, `WebhookChannel` | Verified ingress: an external request becomes a control mutation, once. |
|
|
54
|
+
| `Credential`, `CredentialStore`, `CredentialCipher` | The credential boundary and its two ports. |
|
|
55
|
+
| `SqlCredentialStore`, `WebCryptoCipher` | Their durable and AES-256-GCM adapters. |
|
|
56
|
+
| `Migrations` | The package's namespaced migration set and the layer that runs it. |
|
|
57
|
+
| `SystemFlows` | The reserved CLI verb to flow-id catalog. |
|
|
58
|
+
|
|
59
|
+
A host that binds `jev.session` supplies its existing evaluator through
|
|
60
|
+
`Health.makeRegistry(config, kind, evaluator)`. Native hosts use a subscription
|
|
61
|
+
seat. Missing configuration, unavailable seats and invalid judgments produce
|
|
62
|
+
`probe-error`, never a healthy result. No gateway key or separate auth path is
|
|
63
|
+
used.
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { Control } from "@smthrs/control"
|
|
67
|
+
import { Effect } from "effect"
|
|
68
|
+
|
|
69
|
+
const program = Effect.gen(function*() {
|
|
70
|
+
const control = yield* Control.Control
|
|
71
|
+
return yield* control.list({ _tag: "runs" })
|
|
72
|
+
}).pipe(Effect.provide(Control.layerNoop))
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Use `ControlLive.layer` for in-process operation, `ControlClient.layer({ url, credential })`
|
|
76
|
+
for authenticated RPC, or `ControlRuntime.layerMemory()` when assembling a
|
|
77
|
+
deterministic runtime. `@smthrs/control/package.json` is also exported;
|
|
78
|
+
`internal/*` and nested `*/index` subpaths are blocked.
|
|
79
|
+
|
|
80
|
+
## Receipts and failures
|
|
81
|
+
|
|
82
|
+
Every mutation answers a `ControlSchema.Receipt` rather than throwing on a
|
|
83
|
+
second ask. `Accepted` means this call did the work, `AlreadyApplied` means an
|
|
84
|
+
earlier call under the same idempotency key did, `Conflict` means the key names
|
|
85
|
+
a different intent, `Parked` means the plan is waiting for an approval, and
|
|
86
|
+
`Terminal` means the run had already settled and reports the status it settled
|
|
87
|
+
with.
|
|
88
|
+
|
|
89
|
+
For `signal`, `Accepted` means durable admission. The command and its receipt
|
|
90
|
+
commit before execution observes the payload. Delivery is tracked separately
|
|
91
|
+
by `ControlRuntime.signalCommand`: `pending`, `delivered`, `rejected`, or
|
|
92
|
+
`terminal`. A definite incompatible wait still raises `NoMatchingWait`, and
|
|
93
|
+
that rejected disposition survives retries. Admission emits
|
|
94
|
+
`control.signal.admitted`; queued commands are never announced as delivered.
|
|
95
|
+
|
|
96
|
+
Before its first wait, each mutation copies only bounded JSON own data fields
|
|
97
|
+
and schema-decodes that detached value. Its durable fingerprint is a canonical
|
|
98
|
+
SHA-256 digest, and an authenticated request namespaces its idempotency key by
|
|
99
|
+
the principal's stable `kind` and `id`, not the changing server timestamp.
|
|
100
|
+
Accessors, `toJSON`, sparse arrays, cycles, and non-JSON objects are refused
|
|
101
|
+
with `InvalidInput` before any collaborator sees them.
|
|
102
|
+
|
|
103
|
+
`Channels.ingest` copies inbound bytes and own string header fields before
|
|
104
|
+
verification. A channel lists only the non-secret headers that change its
|
|
105
|
+
decoded command in `fingerprintHeaders`; those names are normalized
|
|
106
|
+
case-insensitively and joined with the body digest. Signature, authorization,
|
|
107
|
+
cookie, token, and credential headers stay outside durable identity. Reusing a
|
|
108
|
+
key with different declared semantics returns `Conflict`, while rotating an
|
|
109
|
+
excluded credential header remains the same delivery.
|
|
110
|
+
|
|
111
|
+
| Verb | Receipts | Typed failures |
|
|
112
|
+
| -------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
113
|
+
| `plan` | returns a `PlanCard`, not a receipt | `FlowNotFound`, `InvalidInput`, `PersistenceError`, `Unavailable` |
|
|
114
|
+
| `run` (`Plan`) | `Accepted`, `AlreadyApplied`, `Conflict`, `Parked` | `PlanNotFound`, `PlanDenied`, `PlanDigestMismatch`, `EnvelopeMismatch`, `ClaimLost`, `InvalidInput`, `LaunchFailed`, `PersistenceError`, `Unavailable` |
|
|
115
|
+
| `run` (`Resume`), `resume` | `Accepted`, `AlreadyApplied`, `Conflict`, `Terminal` | `RunNotFound`, `ClaimLost`, `CodeDrift`, `InvalidInput`, `PersistenceError`, `Unavailable` |
|
|
116
|
+
| `approve`, `deny` | `Accepted`, `AlreadyApplied`, `Conflict`, `Terminal` | `PlanDigestMismatch`, `EnvelopeMismatch`, `AlreadyResolved`, `PlanNotFound`, `RunNotFound`, `InvalidInput`, `PersistenceError`, `Unavailable` |
|
|
117
|
+
| `steer` | `Accepted`, `AlreadyApplied`, `Conflict`, `Terminal` | `RunNotFound`, `InvalidInput`, `PersistenceError`, `Unavailable` |
|
|
118
|
+
| `signal` | `Accepted`, `AlreadyApplied`, `Conflict`, `Terminal` | `RunNotFound`, `NoMatchingWait`, `InvalidInput`, `PersistenceError`, `Unavailable` |
|
|
119
|
+
| `cancel` | `Accepted`, `Terminal` | `RunNotFound`, `ClaimLost`, `InvalidInput`, `PersistenceError`, `Unavailable` |
|
|
120
|
+
| `list`, `watch` | a page or a stream | every member of `ControlError` |
|
|
121
|
+
|
|
122
|
+
`ControlError.ControlErrorSchema` is the single membership list for the union,
|
|
123
|
+
including `CredentialConflict`, and `ControlClient.isControlError` is derived
|
|
124
|
+
from it. Each class carries a stable `code` (`plan_not_found`, `plan_denied`,
|
|
125
|
+
`run_not_found`, `claim_lost`, `no_matching_wait`, `invalid_input`, and so on)
|
|
126
|
+
that clients may branch on.
|
|
127
|
+
|
|
128
|
+
## Deployment requirements
|
|
129
|
+
|
|
130
|
+
`SqlControlRuntime` reads the engine's own columns for the projections it
|
|
131
|
+
reports: `flows_runs.waiting_reason`, the `flows_run_parents` spawn edges, fork
|
|
132
|
+
markers and `flows.engine.interrupted` entries in `flows_journal_events`, and
|
|
133
|
+
`cancel_requested_at_ms`. It reads them through the `SqlClient` it was built
|
|
134
|
+
over, so a composition that wants `RunSummary.waitingReason`, engine-created
|
|
135
|
+
children and forks in `list`, or `source: "engine"` cancel attribution must give
|
|
136
|
+
the control runtime and the engine ONE database.
|
|
137
|
+
|
|
138
|
+
The shipped `smthrs` CLI does not: it keeps `.flows/control.db` and
|
|
139
|
+
`.flows/engine.db` as two files, so one run has two rows. Cancellation still
|
|
140
|
+
converges, because the request is recorded on the engine row through the
|
|
141
|
+
`ControlExecutor` port and the owning driver settles from it. The projections
|
|
142
|
+
above are empty there.
|
|
143
|
+
|
|
144
|
+
## Limits
|
|
145
|
+
|
|
146
|
+
| Bound | Value | Refusal |
|
|
147
|
+
| --------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
148
|
+
| `list` page size | `ControlSchema.defaultPageSize` (100) by default, `ControlSchema.maxPageSize` (500) maximum | `InvalidInput` with code `invalid_input`, naming `limit` |
|
|
149
|
+
| `list` cursor | only a cursor a previous page returned | `InvalidInput`, naming `cursor` |
|
|
150
|
+
| `list` run filters | `runId`, `flowId`, `status`, `parentRunId`, `lineageId` | `InvalidInput` for `principalId`, which rc.0 records nothing to evaluate |
|
|
151
|
+
| `list` trigger listings | `triggers` filters `triggerId`, `flowId`, `enabled`; `fires` filters `triggerId`, `runId`, `outcome` | `InvalidInput` naming `this host serves no trigger store` when no `DispatchReader` is provided |
|
|
152
|
+
| `watch` cursor | `afterSequence` requires `runId` | `InvalidInput`, naming `afterSequence` |
|
|
153
|
+
| `watch` follow-mode handoff | one high-water mark per partition present when the watch starts | snapshot rows at or below the mark; buffered tail rows above it |
|
|
154
|
+
| `watch` partition reads | 8 partition snapshots at a time, plus one reserved slot for the live tail | queued, never refused |
|
|
155
|
+
| webhook request body | `WebhookChannel.maximumBodyBytes` (1 MiB), lowered per mount by `handler`'s third argument | `InvalidInput` naming both byte counts, before the read when `content-length` declares it |
|
|
156
|
+
| mutation identity | 4 MiB, 128 levels, 100,000 values and members; idempotency keys are 1 to 1,024 characters | `InvalidInput` before the first wait |
|
|
157
|
+
|
|
158
|
+
A `steer` whose `message.runId` disagrees with the run the call names is
|
|
159
|
+
refused with `InvalidInput` before anything is admitted to the queue.
|
|
160
|
+
|
|
161
|
+
Approval and denial default to the exact identity `local/operator`, for both
|
|
162
|
+
plan and node targets and all grant scopes. The memory adapter's own default
|
|
163
|
+
also delegates its `memory/test` identity. Authentication
|
|
164
|
+
and approval authority are independent: a custom operator identity has no
|
|
165
|
+
authority until the host explicitly delegates it. Hosts may delegate exact
|
|
166
|
+
identity tuples, including agents, with specific target kinds and approval
|
|
167
|
+
scopes. Denial requires a delegated target kind and installs no grant. Callers
|
|
168
|
+
without authority receive `Unauthorized` (`code: "unauthorized"`) before target
|
|
169
|
+
reads or receipt replay. See [who may decide](docs/guides/approvals.md#who-may-decide).
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-owned approval authority, separate from principal attribution and from
|
|
3
|
+
* the permissions a workflow receives after approval.
|
|
4
|
+
*
|
|
5
|
+
* @since 1.0.0
|
|
6
|
+
*/
|
|
7
|
+
import { Effect, Schema } from "effect";
|
|
8
|
+
import { InvalidInput, type PersistenceError, Unauthorized } from "./ControlError.ts";
|
|
9
|
+
import { type ApprovalTarget, GrantScope, type Principal } from "./ControlSchema.ts";
|
|
10
|
+
/**
|
|
11
|
+
* An approval decision whose caller has already been authenticated by its host.
|
|
12
|
+
* @category models
|
|
13
|
+
* @since 1.0.0
|
|
14
|
+
*/
|
|
15
|
+
export interface Request {
|
|
16
|
+
readonly principal: Principal;
|
|
17
|
+
readonly target: ApprovalTarget;
|
|
18
|
+
readonly decision: "approved" | "denied";
|
|
19
|
+
readonly scope: GrantScope;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A trusted host policy. Both refusals and unavailable policy storage fail
|
|
23
|
+
* closed. Implementations must be bounded and safe inside a write transaction;
|
|
24
|
+
* they must not recursively invoke Control or perform the gated work.
|
|
25
|
+
* @category services
|
|
26
|
+
* @since 1.0.0
|
|
27
|
+
*/
|
|
28
|
+
export interface Service {
|
|
29
|
+
readonly authorize: (request: Request) => Effect.Effect<void, Unauthorized | PersistenceError>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* An explicit delegation to one authenticated identity, not everyone whose
|
|
33
|
+
* kind resembles a role. Scopes are exact, not implicitly hierarchical. A
|
|
34
|
+
* delegation may approve only its listed scopes and may deny either target
|
|
35
|
+
* kind it names (denial installs no grant).
|
|
36
|
+
* Delegation is reusable: `scopes: ["once"]` permits once-scoped grants, not
|
|
37
|
+
* one lifetime decision. Use a host policy for expiry or one-use delegation.
|
|
38
|
+
* @category schemas
|
|
39
|
+
* @since 1.0.0
|
|
40
|
+
*/
|
|
41
|
+
export declare const Delegation: Schema.Struct<{
|
|
42
|
+
readonly principal: Schema.Struct<{
|
|
43
|
+
readonly id: Schema.String;
|
|
44
|
+
readonly kind: Schema.String;
|
|
45
|
+
}>;
|
|
46
|
+
readonly scopes: Schema.$Array<Schema.Literals<readonly ["once", "run", "remembered"]>>;
|
|
47
|
+
readonly targets: Schema.$Array<Schema.Literals<readonly ["Plan", "Node"]>>;
|
|
48
|
+
}>;
|
|
49
|
+
/**
|
|
50
|
+
* One explicit host-owned approval delegation.
|
|
51
|
+
* @category models
|
|
52
|
+
* @since 1.0.0
|
|
53
|
+
*/
|
|
54
|
+
export type Delegation = typeof Delegation.Type;
|
|
55
|
+
/**
|
|
56
|
+
* Builds an immutable policy from explicit host configuration. Invalid
|
|
57
|
+
* configuration is refused without including its contents in the error.
|
|
58
|
+
* The caller's arrays and objects are not retained after acquisition.
|
|
59
|
+
* @category constructors
|
|
60
|
+
* @since 1.0.0
|
|
61
|
+
*/
|
|
62
|
+
export declare const make: (delegations: ReadonlyArray<Delegation>) => Effect.Effect<Service, InvalidInput>;
|
|
63
|
+
/**
|
|
64
|
+
* Default trusted-local policy. Only the local operator identity is an
|
|
65
|
+
* approver. A custom actor, gateway identity, or agent needs explicit host
|
|
66
|
+
* delegation; setting Principal.kind is not itself an authorization. The
|
|
67
|
+
* in-memory test adapter's `memory`/`test` identity is delegated only by that
|
|
68
|
+
* adapter's own default policy, never here.
|
|
69
|
+
* @category policies
|
|
70
|
+
* @since 1.0.0
|
|
71
|
+
*/
|
|
72
|
+
export declare const local: Service;
|
|
73
|
+
//# sourceMappingURL=ApprovalAuthority.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApprovalAuthority.d.ts","sourceRoot":"","sources":["../../src/ApprovalAuthority.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrF,OAAO,EAAE,KAAK,cAAc,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAEpF;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,QAAQ,CAAC,QAAQ,EAAE,UAAU,GAAG,QAAQ,CAAA;IACxC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,gBAAgB,CAAC,CAAA;CAC/F;AAID;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU;;;;;;;EAIrB,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA;AA4B/C;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,GACf,aAAa,aAAa,CAAC,UAAU,CAAC,KACrC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAMnC,CAAA;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,KAAK,EAAE,OAElB,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var ApprovalAuthority_exports = {};
|
|
20
|
+
__export(ApprovalAuthority_exports, {
|
|
21
|
+
Delegation: () => Delegation,
|
|
22
|
+
local: () => local,
|
|
23
|
+
make: () => make
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(ApprovalAuthority_exports);
|
|
26
|
+
var import_effect = require("effect");
|
|
27
|
+
var import_ControlError = require("./ControlError.js");
|
|
28
|
+
var import_ControlSchema = require("./ControlSchema.js");
|
|
29
|
+
const IdentityPart = import_effect.Schema.String.check(import_effect.Schema.isMinLength(1), import_effect.Schema.isMaxLength(1024));
|
|
30
|
+
const Delegation = import_effect.Schema.Struct({
|
|
31
|
+
principal: import_effect.Schema.Struct({ id: IdentityPart, kind: IdentityPart }),
|
|
32
|
+
scopes: import_effect.Schema.Array(import_ControlSchema.GrantScope).check(import_effect.Schema.isMinLength(1), import_effect.Schema.isMaxLength(3)),
|
|
33
|
+
targets: import_effect.Schema.Array(import_effect.Schema.Literals(["Plan", "Node"])).check(import_effect.Schema.isMinLength(1), import_effect.Schema.isMaxLength(2))
|
|
34
|
+
});
|
|
35
|
+
const identity = (principal) => JSON.stringify([principal.id, principal.kind]);
|
|
36
|
+
const compile = (delegations) => {
|
|
37
|
+
const permissions = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const delegation of delegations) {
|
|
39
|
+
for (const target of delegation.targets) {
|
|
40
|
+
const key = JSON.stringify([identity(delegation.principal), target]);
|
|
41
|
+
const scopes = permissions.get(key) ?? /* @__PURE__ */ new Set();
|
|
42
|
+
for (const scope of delegation.scopes) scopes.add(scope);
|
|
43
|
+
permissions.set(key, scopes);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
authorize: (request) => import_effect.Effect.suspend(() => {
|
|
48
|
+
const scopes = permissions.get(JSON.stringify([identity(request.principal), request.target._tag]));
|
|
49
|
+
return scopes !== void 0 && (request.decision === "denied" || request.decision === "approved" && scopes.has(request.scope)) ? import_effect.Effect.void : import_effect.Effect.fail(new import_ControlError.Unauthorized({ message: "This caller has no authority to make this approval decision" }));
|
|
50
|
+
})
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const make = (delegations) => import_effect.Schema.decodeUnknownEffect(import_effect.Schema.Array(Delegation).check(import_effect.Schema.isMaxLength(1024)))(delegations, {
|
|
54
|
+
onExcessProperty: "error"
|
|
55
|
+
}).pipe(
|
|
56
|
+
import_effect.Effect.mapError(() => new import_ControlError.InvalidInput({ issue: "Invalid approval-authority delegation configuration" })),
|
|
57
|
+
import_effect.Effect.map(compile)
|
|
58
|
+
);
|
|
59
|
+
const local = compile([
|
|
60
|
+
{ principal: { id: "local", kind: "operator" }, scopes: ["once", "run", "remembered"], targets: ["Plan", "Node"] }
|
|
61
|
+
]);
|
|
62
|
+
//# sourceMappingURL=ApprovalAuthority.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/ApprovalAuthority.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Host-owned approval authority, separate from principal attribution and from\n * the permissions a workflow receives after approval.\n *\n * @since 1.0.0\n */\n\nimport { Effect, Schema } from \"effect\"\nimport { InvalidInput, type PersistenceError, Unauthorized } from \"./ControlError.ts\"\nimport { type ApprovalTarget, GrantScope, type Principal } from \"./ControlSchema.ts\"\n\n/**\n * An approval decision whose caller has already been authenticated by its host.\n * @category models\n * @since 1.0.0\n */\nexport interface Request {\n readonly principal: Principal\n readonly target: ApprovalTarget\n readonly decision: \"approved\" | \"denied\"\n readonly scope: GrantScope\n}\n\n/**\n * A trusted host policy. Both refusals and unavailable policy storage fail\n * closed. Implementations must be bounded and safe inside a write transaction;\n * they must not recursively invoke Control or perform the gated work.\n * @category services\n * @since 1.0.0\n */\nexport interface Service {\n readonly authorize: (request: Request) => Effect.Effect<void, Unauthorized | PersistenceError>\n}\n\nconst IdentityPart = Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(1024))\n\n/**\n * An explicit delegation to one authenticated identity, not everyone whose\n * kind resembles a role. Scopes are exact, not implicitly hierarchical. A\n * delegation may approve only its listed scopes and may deny either target\n * kind it names (denial installs no grant).\n * Delegation is reusable: `scopes: [\"once\"]` permits once-scoped grants, not\n * one lifetime decision. Use a host policy for expiry or one-use delegation.\n * @category schemas\n * @since 1.0.0\n */\nexport const Delegation = Schema.Struct({\n principal: Schema.Struct({ id: IdentityPart, kind: IdentityPart }),\n scopes: Schema.Array(GrantScope).check(Schema.isMinLength(1), Schema.isMaxLength(3)),\n targets: Schema.Array(Schema.Literals([\"Plan\", \"Node\"])).check(Schema.isMinLength(1), Schema.isMaxLength(2))\n})\n\n/**\n * One explicit host-owned approval delegation.\n * @category models\n * @since 1.0.0\n */\nexport type Delegation = typeof Delegation.Type\n\nconst identity = (principal: Pick<Principal, \"id\" | \"kind\">): string => JSON.stringify([principal.id, principal.kind])\n\nconst compile = (delegations: ReadonlyArray<Delegation>): Service => {\n // Separate target keys preserve each delegation's target/scope pairing;\n // unioning both dimensions independently would grant a cross product.\n const permissions = new Map<string, Set<GrantScope>>()\n for (const delegation of delegations) {\n for (const target of delegation.targets) {\n const key = JSON.stringify([identity(delegation.principal), target])\n const scopes = permissions.get(key) ?? new Set<GrantScope>()\n for (const scope of delegation.scopes) scopes.add(scope)\n permissions.set(key, scopes)\n }\n }\n return Object.freeze({\n authorize: (request: Request) =>\n Effect.suspend(() => {\n const scopes = permissions.get(JSON.stringify([identity(request.principal), request.target._tag]))\n return scopes !== undefined &&\n (request.decision === \"denied\" || (request.decision === \"approved\" && scopes.has(request.scope)))\n ? Effect.void\n : Effect.fail(new Unauthorized({ message: \"This caller has no authority to make this approval decision\" }))\n })\n })\n}\n\n/**\n * Builds an immutable policy from explicit host configuration. Invalid\n * configuration is refused without including its contents in the error.\n * The caller's arrays and objects are not retained after acquisition.\n * @category constructors\n * @since 1.0.0\n */\nexport const make = (\n delegations: ReadonlyArray<Delegation>\n): Effect.Effect<Service, InvalidInput> =>\n Schema.decodeUnknownEffect(Schema.Array(Delegation).check(Schema.isMaxLength(1024)))(delegations, {\n onExcessProperty: \"error\"\n }).pipe(\n Effect.mapError(() => new InvalidInput({ issue: \"Invalid approval-authority delegation configuration\" })),\n Effect.map(compile)\n )\n\n/**\n * Default trusted-local policy. Only the local operator identity is an\n * approver. A custom actor, gateway identity, or agent needs explicit host\n * delegation; setting Principal.kind is not itself an authorization. The\n * in-memory test adapter's `memory`/`test` identity is delegated only by that\n * adapter's own default policy, never here.\n * @category policies\n * @since 1.0.0\n */\nexport const local: Service = compile([\n { principal: { id: \"local\", kind: \"operator\" }, scopes: [\"once\", \"run\", \"remembered\"], targets: [\"Plan\", \"Node\"] }\n])\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,oBAA+B;AAC/B,0BAAkE;AAClE,2BAAgE;AAyBhE,MAAM,eAAe,qBAAO,OAAO,MAAM,qBAAO,YAAY,CAAC,GAAG,qBAAO,YAAY,IAAI,CAAC;AAYjF,MAAM,aAAa,qBAAO,OAAO;AAAA,EACtC,WAAW,qBAAO,OAAO,EAAE,IAAI,cAAc,MAAM,aAAa,CAAC;AAAA,EACjE,QAAQ,qBAAO,MAAM,+BAAU,EAAE,MAAM,qBAAO,YAAY,CAAC,GAAG,qBAAO,YAAY,CAAC,CAAC;AAAA,EACnF,SAAS,qBAAO,MAAM,qBAAO,SAAS,CAAC,QAAQ,MAAM,CAAC,CAAC,EAAE,MAAM,qBAAO,YAAY,CAAC,GAAG,qBAAO,YAAY,CAAC,CAAC;AAC7G,CAAC;AASD,MAAM,WAAW,CAAC,cAAsD,KAAK,UAAU,CAAC,UAAU,IAAI,UAAU,IAAI,CAAC;AAErH,MAAM,UAAU,CAAC,gBAAoD;AAGnE,QAAM,cAAc,oBAAI,IAA6B;AACrD,aAAW,cAAc,aAAa;AACpC,eAAW,UAAU,WAAW,SAAS;AACvC,YAAM,MAAM,KAAK,UAAU,CAAC,SAAS,WAAW,SAAS,GAAG,MAAM,CAAC;AACnE,YAAM,SAAS,YAAY,IAAI,GAAG,KAAK,oBAAI,IAAgB;AAC3D,iBAAW,SAAS,WAAW,OAAQ,QAAO,IAAI,KAAK;AACvD,kBAAY,IAAI,KAAK,MAAM;AAAA,IAC7B;AAAA,EACF;AACA,SAAO,OAAO,OAAO;AAAA,IACnB,WAAW,CAAC,YACV,qBAAO,QAAQ,MAAM;AACnB,YAAM,SAAS,YAAY,IAAI,KAAK,UAAU,CAAC,SAAS,QAAQ,SAAS,GAAG,QAAQ,OAAO,IAAI,CAAC,CAAC;AACjG,aAAO,WAAW,WACb,QAAQ,aAAa,YAAa,QAAQ,aAAa,cAAc,OAAO,IAAI,QAAQ,KAAK,KAC9F,qBAAO,OACP,qBAAO,KAAK,IAAI,iCAAa,EAAE,SAAS,8DAA8D,CAAC,CAAC;AAAA,IAC9G,CAAC;AAAA,EACL,CAAC;AACH;AASO,MAAM,OAAO,CAClB,gBAEA,qBAAO,oBAAoB,qBAAO,MAAM,UAAU,EAAE,MAAM,qBAAO,YAAY,IAAI,CAAC,CAAC,EAAE,aAAa;AAAA,EAChG,kBAAkB;AACpB,CAAC,EAAE;AAAA,EACD,qBAAO,SAAS,MAAM,IAAI,iCAAa,EAAE,OAAO,sDAAsD,CAAC,CAAC;AAAA,EACxG,qBAAO,IAAI,OAAO;AACpB;AAWK,MAAM,QAAiB,QAAQ;AAAA,EACpC,EAAE,WAAW,EAAE,IAAI,SAAS,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,OAAO,YAAY,GAAG,SAAS,CAAC,QAAQ,MAAM,EAAE;AACnH,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|