firedrill-run 2.2.5 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +178 -22
- package/bin/firedrill.mjs +29 -5
- package/dist/assembly.json +13 -0
- package/dist/cli/runtime/candidate_copy.py +395 -0
- package/dist/cli/runtime/source_snapshot.py +391 -0
- package/dist/cli/src/administration.js +295 -0
- package/dist/cli/src/agent-changes.js +496 -0
- package/dist/cli/src/assessment-requests.js +67 -0
- package/dist/cli/src/auth.js +465 -0
- package/dist/cli/src/billing-commerce-contracts.js +1 -0
- package/dist/cli/src/billing-usage.js +227 -0
- package/dist/cli/src/billing-wallet-contracts.js +1 -0
- package/dist/cli/src/billing.js +170 -0
- package/dist/cli/src/bootstrap-process-lock.js +136 -0
- package/dist/cli/src/browser-links.js +14 -0
- package/dist/cli/src/campaign-controls.js +122 -0
- package/dist/cli/src/campaign-diagnoses.js +118 -0
- package/dist/cli/src/campaign-reports.js +1215 -0
- package/dist/cli/src/campaign-world.js +156 -0
- package/dist/cli/src/candidate-copy.js +376 -0
- package/dist/cli/src/catalog-contracts.js +1 -0
- package/dist/cli/src/ci-access-contracts.js +1 -0
- package/dist/cli/src/ci-configuration-contracts.js +1 -0
- package/dist/cli/src/ci-coverage.js +64 -0
- package/dist/cli/src/ci-delivery-contracts.js +1 -0
- package/dist/cli/src/ci-result-contracts.js +1 -0
- package/dist/cli/src/ci-run-contracts.js +1 -0
- package/dist/cli/src/ci-setup-proposals.js +52 -0
- package/dist/cli/src/company-policies.js +229 -0
- package/dist/cli/src/completion.js +79 -0
- package/dist/cli/src/configuration-intents.js +277 -0
- package/dist/cli/src/configuration.js +369 -0
- package/dist/cli/src/continuous-simulation.js +277 -0
- package/dist/cli/src/coordinated-checkpoints.js +133 -0
- package/dist/cli/src/credential-mode.js +139 -0
- package/dist/cli/src/credentials.js +331 -0
- package/dist/cli/src/credit-format.js +8 -0
- package/dist/cli/src/dataset-contracts.js +1 -0
- package/dist/cli/src/dataset-export.js +154 -0
- package/dist/cli/src/dataset-reads.js +37 -0
- package/dist/cli/src/dependency-preparation.js +239 -0
- package/dist/cli/src/director-tool-setup.js +104 -0
- package/dist/cli/src/driver-review.js +225 -0
- package/dist/cli/src/evaluation-authoring.js +315 -0
- package/dist/cli/src/evidence-bundles.js +367 -0
- package/dist/cli/src/execution-proposals.js +36 -0
- package/dist/cli/src/http.js +302 -0
- package/dist/cli/src/local-container-boundary.js +38 -0
- package/dist/cli/src/local-container-policy.js +201 -0
- package/dist/cli/src/local-execution-setup.js +81 -0
- package/dist/cli/src/local-source-basis.js +73 -0
- package/dist/cli/src/local-source.js +66 -0
- package/dist/cli/src/local-value-store.js +91 -0
- package/dist/cli/src/local-values.js +163 -0
- package/dist/cli/src/login-organizations.js +70 -0
- package/dist/cli/src/main.js +1622 -0
- package/dist/cli/src/mcp-connection.js +109 -0
- package/dist/cli/src/native/bindings.js +137 -0
- package/dist/cli/src/native/canonical.js +370 -0
- package/dist/cli/src/native/cloud-resources.js +942 -0
- package/dist/cli/src/native/companion-channel.js +421 -0
- package/dist/cli/src/native/companion-ipc.js +473 -0
- package/dist/cli/src/native/contracts.js +218 -0
- package/dist/cli/src/native/control-plane.js +1354 -0
- package/dist/cli/src/native/credit-approval.js +15 -0
- package/dist/cli/src/native/dependency-proxy.js +1006 -0
- package/dist/cli/src/native/drill-cleanup.js +115 -0
- package/dist/cli/src/native/drill-runner.js +1562 -0
- package/dist/cli/src/native/drivers/action-trace.js +210 -0
- package/dist/cli/src/native/drivers/function-wrapper.js +152 -0
- package/dist/cli/src/native/drivers/http.js +442 -0
- package/dist/cli/src/native/drivers/index.js +47 -0
- package/dist/cli/src/native/drivers/jsonl-process.js +538 -0
- package/dist/cli/src/native/drivers/playwright.js +600 -0
- package/dist/cli/src/native/drivers/signed-event.js +244 -0
- package/dist/cli/src/native/drivers/types.js +578 -0
- package/dist/cli/src/native/evidence-filter.js +255 -0
- package/dist/cli/src/native/isolated-access.js +241 -0
- package/dist/cli/src/native/library-sharing.js +220 -0
- package/dist/cli/src/native/local-run.js +667 -0
- package/dist/cli/src/native/local-secrets.js +19 -0
- package/dist/cli/src/native/mcp-config.js +123 -0
- package/dist/cli/src/native/metadata-requests.js +120 -0
- package/dist/cli/src/native/observations.js +1159 -0
- package/dist/cli/src/native/owned-groups.js +46 -0
- package/dist/cli/src/native/plan.js +594 -0
- package/dist/cli/src/native/png.js +159 -0
- package/dist/cli/src/native/ports.js +43 -0
- package/dist/cli/src/native/readiness.js +139 -0
- package/dist/cli/src/native/reassessments.js +206 -0
- package/dist/cli/src/native/redaction.js +235 -0
- package/dist/cli/src/native/registration.js +155 -0
- package/dist/cli/src/native/roots.js +110 -0
- package/dist/cli/src/native/run-cleanup.js +199 -0
- package/dist/cli/src/native/scratch.js +117 -0
- package/dist/cli/src/native/screenshots.js +60 -0
- package/dist/cli/src/native/session.js +556 -0
- package/dist/cli/src/native/standalone-proxy.js +580 -0
- package/dist/cli/src/native/standalone-renewals.js +183 -0
- package/dist/cli/src/native/standalone-state.js +193 -0
- package/dist/cli/src/native/standalone-tools.js +187 -0
- package/dist/cli/src/native/supervisor.js +831 -0
- package/dist/cli/src/native/target-auth.js +161 -0
- package/dist/cli/src/native/target-state.js +330 -0
- package/dist/cli/src/native/tool-reuse.js +364 -0
- package/dist/cli/src/native/tool-setups.js +336 -0
- package/dist/cli/src/native/world-reuse.js +288 -0
- package/dist/cli/src/onboarding.js +23 -0
- package/dist/cli/src/priority-requests.js +70 -0
- package/dist/cli/src/priority.js +223 -0
- package/dist/cli/src/prompts.js +184 -0
- package/dist/cli/src/real-operations.js +221 -0
- package/dist/cli/src/recipe-intents.js +58 -0
- package/dist/cli/src/recorded-context-intents.js +59 -0
- package/dist/cli/src/recorded-context.js +248 -0
- package/dist/cli/src/recordings.js +69 -0
- package/dist/cli/src/registration-guide.js +39 -0
- package/dist/cli/src/report-exports.js +213 -0
- package/dist/cli/src/request-input.js +47 -0
- package/dist/cli/src/resource-lifecycle.js +141 -0
- package/dist/cli/src/revision-requests.js +55 -0
- package/dist/cli/src/runner-abandon.js +53 -0
- package/dist/cli/src/runner-campaign-controls.js +262 -0
- package/dist/cli/src/runner-claim-reads.js +36 -0
- package/dist/cli/src/runner-completion.js +65 -0
- package/dist/cli/src/runner-configuration.js +546 -0
- package/dist/cli/src/runner-container.js +794 -0
- package/dist/cli/src/runner-evidence-erasure.js +351 -0
- package/dist/cli/src/runner-evidence-privacy.js +37 -0
- package/dist/cli/src/runner-evidence-retention.js +161 -0
- package/dist/cli/src/runner-evidence.js +326 -0
- package/dist/cli/src/runner-execute.js +92 -0
- package/dist/cli/src/runner-execution-deadline.js +25 -0
- package/dist/cli/src/runner-grants.js +307 -0
- package/dist/cli/src/runner-identity.js +615 -0
- package/dist/cli/src/runner-inputs.js +308 -0
- package/dist/cli/src/runner-jobs.js +49 -0
- package/dist/cli/src/runner-model-transport.js +392 -0
- package/dist/cli/src/runner-ownership.js +332 -0
- package/dist/cli/src/runner-process-lock.js +175 -0
- package/dist/cli/src/runner-runtime.js +396 -0
- package/dist/cli/src/runner-session-channel.js +377 -0
- package/dist/cli/src/runner-trial-completion.js +34 -0
- package/dist/cli/src/runner-trial-journal.js +358 -0
- package/dist/cli/src/runner-trial-live.js +393 -0
- package/dist/cli/src/runner-trial-protocol.js +289 -0
- package/dist/cli/src/runner-trial-sync.js +110 -0
- package/dist/cli/src/runner-trial-transfer.js +107 -0
- package/dist/cli/src/runner-voice.js +40 -0
- package/dist/cli/src/runner-world-claim.js +21 -0
- package/dist/cli/src/runner-world-collector.js +159 -0
- package/dist/cli/src/runner-world-command-evidence.js +487 -0
- package/dist/cli/src/runner-world-commands.js +268 -0
- package/dist/cli/src/runner-world-completion.js +76 -0
- package/dist/cli/src/runner-world-erasure.js +95 -0
- package/dist/cli/src/runner-world-evidence-sync.js +91 -0
- package/dist/cli/src/runner-world-journal.js +510 -0
- package/dist/cli/src/runner-world-native-filters.js +134 -0
- package/dist/cli/src/runner-world-observations.js +50 -0
- package/dist/cli/src/runner-world-session-protocol.js +134 -0
- package/dist/cli/src/saved-records.js +40 -0
- package/dist/cli/src/scenario-authoring.js +212 -0
- package/dist/cli/src/scenario-discovery.js +216 -0
- package/dist/cli/src/scenario-paths.js +68 -0
- package/dist/cli/src/scenario-requests.js +4 -0
- package/dist/cli/src/service-receipts.js +105 -0
- package/dist/cli/src/simple/authoring.js +270 -0
- package/dist/cli/src/simple/credit-approval.js +16 -0
- package/dist/cli/src/simple/help.js +98 -0
- package/dist/cli/src/simple/init.js +61 -0
- package/dist/cli/src/simple/library-sharing.js +414 -0
- package/dist/cli/src/simple/metadata-requests.js +46 -0
- package/dist/cli/src/simple/native-report.js +841 -0
- package/dist/cli/src/simple/native-tools.js +780 -0
- package/dist/cli/src/simple/plan-apply.js +506 -0
- package/dist/cli/src/simple/reassessment.js +323 -0
- package/dist/cli/src/simple/register.js +123 -0
- package/dist/cli/src/simple/run.js +122 -0
- package/dist/cli/src/simple/status.js +49 -0
- package/dist/cli/src/simple/tool-renewal.js +308 -0
- package/dist/cli/src/simple/tool-reuse.js +526 -0
- package/dist/cli/src/simple/tool-start-catalog.js +100 -0
- package/dist/cli/src/simple/tool-state.js +426 -0
- package/dist/cli/src/simple/tools-author.js +222 -0
- package/dist/cli/src/simple/watch.js +28 -0
- package/dist/cli/src/simple/world-reuse.js +586 -0
- package/dist/cli/src/simulation-intents.js +406 -0
- package/dist/cli/src/simulation-run.js +1058 -0
- package/dist/cli/src/source-batch.js +322 -0
- package/dist/cli/src/source-connection.js +451 -0
- package/dist/cli/src/source-runtime.js +346 -0
- package/dist/cli/src/source-selection-intents.js +75 -0
- package/dist/cli/src/source-sets.js +214 -0
- package/dist/cli/src/target-models.js +109 -0
- package/dist/cli/src/tool-catalog.js +224 -0
- package/dist/cli/src/tool-command-contracts.js +1 -0
- package/dist/cli/src/tool-command-export.js +245 -0
- package/dist/cli/src/tool-connection-contracts.js +1 -0
- package/dist/cli/src/tool-connection-reads.js +23 -0
- package/dist/cli/src/tool-contributions.js +58 -0
- package/dist/cli/src/tool-data.js +116 -0
- package/dist/cli/src/tool-datasets.js +176 -0
- package/dist/cli/src/tool-group-contracts.js +1 -0
- package/dist/cli/src/tool-group-reads.js +26 -0
- package/dist/cli/src/tool-group-state.js +147 -0
- package/dist/cli/src/tool-groups.js +311 -0
- package/dist/cli/src/tool-instances.js +186 -0
- package/dist/cli/src/tool-lifecycle-contracts.js +1 -0
- package/dist/cli/src/tool-lifecycle-reads.js +30 -0
- package/dist/cli/src/tool-lifecycle.js +323 -0
- package/dist/cli/src/tool-package-contracts.js +1 -0
- package/dist/cli/src/tool-package-reads.js +41 -0
- package/dist/cli/src/tool-records.js +53 -0
- package/dist/cli/src/tool-runtime.js +96 -0
- package/dist/cli/src/tool-state-contracts.js +1 -0
- package/dist/cli/src/tool-state-reads.js +31 -0
- package/dist/cli/src/tools.js +306 -0
- package/dist/cli/src/trial-actions.js +93 -0
- package/dist/cli/src/trial-checkpoints.js +133 -0
- package/dist/cli/src/trial-checks.js +70 -0
- package/dist/cli/src/trial-state.js +197 -0
- package/dist/cli/src/vault.js +266 -0
- package/dist/cli/src/workspace-registration.js +383 -0
- package/dist/cli/src/workspace-team-contracts.js +1 -0
- package/dist/cli/src/world-access.js +231 -0
- package/dist/cli/src/world-agent.js +4 -0
- package/dist/cli/src/world-checkpoint-scopes.js +15 -0
- package/dist/cli/src/world-contracts.js +6 -0
- package/dist/cli/src/world-creation.js +201 -0
- package/dist/cli/src/world-datasets.js +207 -0
- package/dist/cli/src/world-inspection.js +257 -0
- package/dist/cli/src/world-recipes.js +103 -0
- package/dist/cli/src/world-requests.js +241 -0
- package/dist/cli/src/world-session-checkpoints.js +196 -0
- package/dist/cli/src/world-session-lifecycle.js +207 -0
- package/dist/cli/src/world-session-requests.js +215 -0
- package/dist/cli/src/world-session-state.js +145 -0
- package/dist/cli/src/world-session-voice.js +66 -0
- package/dist/cli/src/world-sessions.js +288 -0
- package/dist/cli/src/world-stream.js +99 -0
- package/dist/cli/src/world-time-report.js +58 -0
- package/dist/contracts/agent-change-contracts.js +75 -0
- package/dist/contracts/agent-execution-contracts.js +38 -0
- package/dist/contracts/application-state-contracts.js +26 -0
- package/dist/contracts/assessment-aggregate-contracts.js +15 -0
- package/dist/contracts/assessment-contracts.js +74 -0
- package/dist/contracts/billing-commerce-contracts.js +107 -0
- package/dist/contracts/billing-wallet-contracts.js +43 -0
- package/dist/contracts/campaign-lifecycle.js +1 -0
- package/dist/contracts/campaign-world-contracts.js +80 -0
- package/dist/contracts/catalog-contracts.js +73 -0
- package/dist/contracts/ci-access-contracts.js +68 -0
- package/dist/contracts/ci-configuration-contracts.js +88 -0
- package/dist/contracts/ci-coverage-contracts.js +65 -0
- package/dist/contracts/ci-coverage-labels.js +25 -0
- package/dist/contracts/ci-delivery-contracts.js +61 -0
- package/dist/contracts/ci-result-contracts.js +103 -0
- package/dist/contracts/ci-run-contracts.js +51 -0
- package/dist/contracts/ci-setup-contracts.js +88 -0
- package/dist/contracts/clip-contracts.js +32 -0
- package/dist/contracts/comparison-contracts.js +53 -0
- package/dist/contracts/composite-contracts.js +34 -0
- package/dist/contracts/context-contracts.js +76 -0
- package/dist/contracts/continuation-report-contracts.js +1 -0
- package/dist/contracts/continuity-requirements.js +8 -0
- package/dist/contracts/coordinated-checkpoint-contracts.js +34 -0
- package/dist/contracts/dataset-contracts.js +88 -0
- package/dist/contracts/dependency-decision-contracts.js +36 -0
- package/dist/contracts/dependency-protocol-contracts.js +43 -0
- package/dist/contracts/director-execution.js +51 -0
- package/dist/contracts/driver-review-contracts.js +99 -0
- package/dist/contracts/evidence-contracts.js +65 -0
- package/dist/contracts/evidence-coverage-contracts.js +10 -0
- package/dist/contracts/export-contracts.js +44 -0
- package/dist/contracts/github-directory-contracts.js +96 -0
- package/dist/contracts/insight-contracts.js +11 -0
- package/dist/contracts/inspection-contracts.js +1 -0
- package/dist/contracts/local-claim-contracts.js +39 -0
- package/dist/contracts/local-configuration-contracts.js +7 -0
- package/dist/contracts/local-evidence-contracts.js +32 -0
- package/dist/contracts/local-grant-contracts.js +83 -0
- package/dist/contracts/local-input-contracts.js +19 -0
- package/dist/contracts/local-runner-contracts.js +42 -0
- package/dist/contracts/local-trial-live-contracts.js +16 -0
- package/dist/contracts/local-value-source-contracts.js +92 -0
- package/dist/contracts/local-world-native-contracts.js +8 -0
- package/dist/contracts/mcp-contracts.js +42 -0
- package/dist/contracts/media-contracts.js +28 -0
- package/dist/contracts/native-check-contracts.js +31 -0
- package/dist/contracts/native-identity-contracts.js +52 -0
- package/dist/contracts/onboarding-contracts.js +32 -0
- package/dist/contracts/performance-contracts.js +85 -0
- package/dist/contracts/planning-contracts.js +81 -0
- package/dist/contracts/real-operation-contracts.js +30 -0
- package/dist/contracts/recommendation-contracts.js +54 -0
- package/dist/contracts/report-contracts.js +1 -0
- package/dist/contracts/resource-lifecycle-contracts.js +57 -0
- package/dist/contracts/revision-contracts.js +12 -0
- package/dist/contracts/revision-request-contracts.js +39 -0
- package/dist/contracts/saved-record-contracts.js +76 -0
- package/dist/contracts/scenario-draft-comparison.js +91 -0
- package/dist/contracts/scenario-world-contracts.js +14 -0
- package/dist/contracts/service-contracts.js +1 -0
- package/dist/contracts/session-command-contracts.js +56 -0
- package/dist/contracts/session-contracts.js +65 -0
- package/dist/contracts/session-state-contracts.js +67 -0
- package/dist/contracts/session-voice-contracts.js +45 -0
- package/dist/contracts/source-set-contracts.js +26 -0
- package/dist/contracts/source-upload-contracts.js +22 -0
- package/dist/contracts/tool-command-contracts.js +57 -0
- package/dist/contracts/tool-connection-contracts.js +87 -0
- package/dist/contracts/tool-contribution-contracts.js +35 -0
- package/dist/contracts/tool-group-contracts.js +53 -0
- package/dist/contracts/tool-group-state-contracts.js +63 -0
- package/dist/contracts/tool-lifecycle-contracts.js +94 -0
- package/dist/contracts/tool-package-contracts.js +91 -0
- package/dist/contracts/tool-protocol-contracts.js +71 -0
- package/dist/contracts/tool-runtime-billing-contracts.js +28 -0
- package/dist/contracts/tool-setup-proposal.js +59 -0
- package/dist/contracts/tool-state-contracts.js +79 -0
- package/dist/contracts/trial-state-contracts.js +30 -0
- package/dist/contracts/typescript/agent-change.js +1 -0
- package/dist/contracts/typescript/assessment-aggregate.js +1 -0
- package/dist/contracts/typescript/assessment.js +1 -0
- package/dist/contracts/typescript/billing-commerce.js +1 -0
- package/dist/contracts/typescript/campaigns.js +1 -0
- package/dist/contracts/typescript/catalog.js +1 -0
- package/dist/contracts/typescript/ci-access.js +1 -0
- package/dist/contracts/typescript/ci-configuration.js +1 -0
- package/dist/contracts/typescript/ci-delivery.js +1 -0
- package/dist/contracts/typescript/ci-result.js +1 -0
- package/dist/contracts/typescript/ci-runs.js +1 -0
- package/dist/contracts/typescript/clips.js +1 -0
- package/dist/contracts/typescript/comparison.js +1 -0
- package/dist/contracts/typescript/composite.js +1 -0
- package/dist/contracts/typescript/connections.js +1 -0
- package/dist/contracts/typescript/context.js +1 -0
- package/dist/contracts/typescript/datasets.js +1 -0
- package/dist/contracts/typescript/evidence-coverage.js +1 -0
- package/dist/contracts/typescript/export.js +1 -0
- package/dist/contracts/typescript/github-directory.js +1 -0
- package/dist/contracts/typescript/insight.js +1 -0
- package/dist/contracts/typescript/inspection.js +1 -0
- package/dist/contracts/typescript/intake.js +1 -0
- package/dist/contracts/typescript/local-claim.js +1 -0
- package/dist/contracts/typescript/local-configuration.js +1 -0
- package/dist/contracts/typescript/local-evidence.js +1 -0
- package/dist/contracts/typescript/local-grant.js +1 -0
- package/dist/contracts/typescript/local-input.js +1 -0
- package/dist/contracts/typescript/local-runner.js +1 -0
- package/dist/contracts/typescript/local-trial-live.js +1 -0
- package/dist/contracts/typescript/local-value-source.js +1 -0
- package/dist/contracts/typescript/local-world-native.js +1 -0
- package/dist/contracts/typescript/mcp.js +1 -0
- package/dist/contracts/typescript/media.js +1 -0
- package/dist/contracts/typescript/native-check.js +1 -0
- package/dist/contracts/typescript/native-identity.js +1 -0
- package/dist/contracts/typescript/onboarding.js +1 -0
- package/dist/contracts/typescript/performance.js +1 -0
- package/dist/contracts/typescript/planning.js +1 -0
- package/dist/contracts/typescript/preparation.js +1 -0
- package/dist/contracts/typescript/real-operation.js +1 -0
- package/dist/contracts/typescript/recommendation.js +1 -0
- package/dist/contracts/typescript/reports.js +1 -0
- package/dist/contracts/typescript/resource-lifecycle.js +1 -0
- package/dist/contracts/typescript/saved-record.js +1 -0
- package/dist/contracts/typescript/scenarios.js +1 -0
- package/dist/contracts/typescript/services.js +1 -0
- package/dist/contracts/typescript/session-command.js +1 -0
- package/dist/contracts/typescript/session-state.js +1 -0
- package/dist/contracts/typescript/session-voice.js +1 -0
- package/dist/contracts/typescript/session.js +1 -0
- package/dist/contracts/typescript/tool-command.js +1 -0
- package/dist/contracts/typescript/tool-connection.js +1 -0
- package/dist/contracts/typescript/tool-contribution.js +1 -0
- package/dist/contracts/typescript/tool-groups.js +1 -0
- package/dist/contracts/typescript/tool-lifecycle.js +1 -0
- package/dist/contracts/typescript/tool-package.js +1 -0
- package/dist/contracts/typescript/tool-state.js +1 -0
- package/dist/contracts/typescript/trial-state.js +1 -0
- package/dist/contracts/typescript/vault.js +1 -0
- package/dist/contracts/typescript/workspace-team.js +1 -0
- package/dist/contracts/typescript/world-stream.js +1 -0
- package/dist/contracts/workspace-team-contracts.js +55 -0
- package/dist/contracts/world-command.js +65 -0
- package/dist/contracts/world-lifetime-contracts.js +74 -0
- package/dist/contracts/world-recipe-contracts.js +27 -0
- package/dist/contracts/world-stream-contracts.js +27 -0
- package/dist/package.json +1 -0
- package/package.json +16 -16
- package/LICENSE.md +0 -23
- package/PACKAGING.json +0 -50
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { api } from './auth.js';
|
|
2
|
+
import { CliError } from './http.js';
|
|
3
|
+
import { selectOne } from './prompts.js';
|
|
4
|
+
const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
5
|
+
export async function worldTimeReport(path, scope, interactive, options, output, supplied, suppliedKind) {
|
|
6
|
+
const auth = { actor: scope.owner, workspace: scope.workspace, signal: options.signal };
|
|
7
|
+
const parts = path.split('/');
|
|
8
|
+
const command = `firedrill report ${parts.at(-3)} drill ${parts.at(-1)} schedule`;
|
|
9
|
+
let event = supplied;
|
|
10
|
+
if (event && !/^[a-f0-9]{64}$/.test(event) || suppliedKind && !['changes', 'conditions'].includes(suppliedKind)
|
|
11
|
+
|| !event && options.search)
|
|
12
|
+
throw new CliError('arguments_invalid', 'Choose a schedule event ID, then changes or conditions. Search applies to that event’s entries.', 2);
|
|
13
|
+
if (!event) {
|
|
14
|
+
let page = Number(options.page ?? '1');
|
|
15
|
+
while (true) {
|
|
16
|
+
const data = await api(`${path}/world-time?page=${page}`, auth);
|
|
17
|
+
output(data, [...data.results.map(row => [`Attempt ${row.attempt_number}: ${row.before_turn === null ? row.kind === 'world.time.started' ? 'Schedule started' : 'Schedule stopped' : `Before conversation turn ${row.before_turn + 1}`}`,
|
|
18
|
+
`Scheduled position: ${row.world_at}; offset ${row.offset_ms}ms. Recorded: ${row.recorded_at}.`,
|
|
19
|
+
`${row.change_count.toLocaleString()} changes committed; ${row.condition_count.toLocaleString()} record conditions checked.`,
|
|
20
|
+
...(row.events_pending === null ? [] : [`${row.events_pending.toLocaleString()} changes pending. Unreached offsets and unmet conditions are not agent failures.`]),
|
|
21
|
+
...(row.reconciliation_required ? ['Possible changes could not be confirmed and were not automatically replayed.'] : []), row.id].join('\n')),
|
|
22
|
+
...(!data.count ? ['No world schedule observations are available.'] : []), `Page ${data.page}; ${data.count.toLocaleString()} observations.`,
|
|
23
|
+
...(data.next ? [`Continue: ${command} --workspace ${scope.workspace} --page ${page + 1}`] : []),
|
|
24
|
+
'Schedule offsets are not runtime or an acceleration measurement.'].join('\n\n'));
|
|
25
|
+
if (!interactive || !data.count)
|
|
26
|
+
return;
|
|
27
|
+
const choices = data.results.filter(row => row.change_count || row.condition_count).map(row => ({ value: row.id,
|
|
28
|
+
label: `Attempt ${row.attempt_number}, before turn ${(row.before_turn ?? 0) + 1}`, detail: `${row.change_count} changes; ${row.condition_count} conditions` }));
|
|
29
|
+
if (page > 1)
|
|
30
|
+
choices.push({ value: 'previous', label: 'Previous page', detail: '' });
|
|
31
|
+
if (data.next)
|
|
32
|
+
choices.push({ value: 'next', label: 'Next page', detail: '' });
|
|
33
|
+
choices.push({ value: 'done', label: 'Done', detail: '' });
|
|
34
|
+
const selected = await selectOne('Inspect world schedule', choices, options.signal);
|
|
35
|
+
if (selected === 'done')
|
|
36
|
+
return;
|
|
37
|
+
if (selected === 'previous') {
|
|
38
|
+
page -= 1;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (selected === 'next') {
|
|
42
|
+
page += 1;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
event = selected;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const kind = suppliedKind ?? (interactive ? await selectOne('Inspect event', [{ value: 'changes', label: 'Committed changes' }, { value: 'conditions', label: 'Record conditions' }], options.signal) : 'changes');
|
|
50
|
+
const page = supplied ? options.page ?? '1' : '1';
|
|
51
|
+
const search = supplied ? options.search ?? '' : '';
|
|
52
|
+
const data = await api(`${path}/world-time/${event}/${kind}?page=${page}&q=${encodeURIComponent(search)}`, auth);
|
|
53
|
+
output(data, [...data.results.map(row => 'met' in row ? `${row.id}: ${row.met ? 'Condition met' : 'Condition not met'}\n${row.collection}`
|
|
54
|
+
: `${row.id}: ${row.action} · ${row.collection}\n${row.changed_rows} rows changed at offset ${row.offset_ms}ms.`),
|
|
55
|
+
...(!data.count ? ['No matching event entries.'] : []), `Page ${data.page}; ${data.count.toLocaleString()} matching entries.`,
|
|
56
|
+
...(data.next ? [`Continue: ${command} ${event} ${kind} --workspace ${scope.workspace} --page ${data.page + 1}${search ? ' --search ' + quote(search) : ''}`] : []),
|
|
57
|
+
...(kind === 'conditions' ? ['An unmet condition leaves its record change pending. It is not an agent evaluation result.'] : [])].join('\n\n'));
|
|
58
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { nativeMetadataCanonical } from './local-value-source-contracts.js';
|
|
2
|
+
const uuid = (v) => typeof v === 'string' && /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(v);
|
|
3
|
+
const hex = (v) => typeof v === 'string' && /^[a-f0-9]{64}$/.test(v);
|
|
4
|
+
const date = (v) => typeof v === 'string' && Number.isFinite(Date.parse(v));
|
|
5
|
+
const integer = (v, minimum = 0) => typeof v === 'number' && Number.isSafeInteger(v) && v >= minimum;
|
|
6
|
+
export function sourceChangeRead(v, matches) {
|
|
7
|
+
if (!matches)
|
|
8
|
+
throw new Error('The source-change response did not match this workspace, baseline or original reviewed source. Inspect the original request before continuing. No replacement request was submitted.');
|
|
9
|
+
return v;
|
|
10
|
+
}
|
|
11
|
+
export const patchSourceFileMatches = (v) => !!v && typeof v.path === 'string' && v.path.length > 0
|
|
12
|
+
&& v.path.length <= 1024 && hex(v.sha256) && integer(v.size) && [420, 493].includes(v.mode);
|
|
13
|
+
export function sourceChangeMatches(v, workspace, campaign, change) {
|
|
14
|
+
return !!v && uuid(v.id) && (!change || v.id === change) && v.workspace_id === workspace && v.baseline_id === campaign
|
|
15
|
+
&& [v.world_id, v.source_id, v.request_key, v.proposed_by_id].every(uuid) && typeof v.title === 'string'
|
|
16
|
+
&& typeof v.instruction === 'string' && ['pending', 'approved', 'drafted', 'creating', 'accepted', 'dismissed'].includes(v.state)
|
|
17
|
+
&& typeof v.current === 'boolean' && typeof v.comparison_available === 'boolean' && hex(v.scope_sha256)
|
|
18
|
+
&& (v.draft_sha256 === null || hex(v.draft_sha256)) && date(v.expires_at) && typeof v.source_revision === 'string'
|
|
19
|
+
&& [v.candidate_source_id, v.candidate_world_id, v.approved_by_id].every(one => one === null || uuid(one))
|
|
20
|
+
&& (v.approved_at === null || date(v.approved_at)) && (v.problem === null || typeof v.problem === 'string')
|
|
21
|
+
&& Array.isArray(v.files) && new Set(v.files.map(one => one.path)).size === v.files.length && v.files.every(patchSourceFileMatches)
|
|
22
|
+
&& (v.draft_files === undefined || Array.isArray(v.draft_files) && v.draft_files.length <= v.files.length
|
|
23
|
+
&& new Set(v.draft_files.map(one => one.path)).size === v.draft_files.length
|
|
24
|
+
&& v.draft_files.every(one => one && typeof one.path === 'string' && hex(one.sha256) && hex(one.before_sha256) && integer(one.size)
|
|
25
|
+
&& v.files.some(original => original.path === one.path && original.sha256 === one.before_sha256)));
|
|
26
|
+
}
|
|
27
|
+
export function sourceChangeProposalMatches(v, workspace, campaign, actor, key, body) {
|
|
28
|
+
return sourceChangeMatches(v, workspace, campaign) && v.proposed_by_id === actor && v.request_key === key
|
|
29
|
+
&& v.title === body.title.trim() && v.instruction === body.instruction.trim()
|
|
30
|
+
&& nativeMetadataCanonical(v.files.map(one => one.path).sort()) === nativeMetadataCanonical([...body.paths].sort());
|
|
31
|
+
}
|
|
32
|
+
export function sourceChangeCommandMatches(v, workspace, campaign, change, actor, key, body, digest) {
|
|
33
|
+
return sourceChangeMatches(v, workspace, campaign, change) && v.scope_sha256 === body.scope_sha256
|
|
34
|
+
&& (body.action !== 'accept' || v.draft_sha256 === body.draft_sha256) && !!v.command_receipt
|
|
35
|
+
&& v.command_receipt.actor_id === actor && v.command_receipt.request_key === key && v.command_receipt.action === body.action
|
|
36
|
+
&& v.command_receipt.command_sha256 === digest && typeof v.command_receipt.recovered === 'boolean';
|
|
37
|
+
}
|
|
38
|
+
export function sourceChangePageMatches(v, workspace, campaign, page) {
|
|
39
|
+
return !!v && v.workspace_id === workspace && v.baseline_id === campaign && v.page === page && integer(v.count)
|
|
40
|
+
&& integer(v.page_size, 1) && v.page_size <= 100 && Array.isArray(v.results) && v.results.length <= v.page_size;
|
|
41
|
+
}
|
|
42
|
+
export function sourceChangeDiffMatches(v, row, file, position) {
|
|
43
|
+
return !!v && v.workspace_id === row.workspace_id && v.baseline_id === row.baseline_id && v.change_id === row.id
|
|
44
|
+
&& v.source_id === row.source_id && v.scope_sha256 === row.scope_sha256 && v.draft_sha256 === row.draft_sha256
|
|
45
|
+
&& v.position === position && v.path === file.path && v.before_sha256 === file.before_sha256 && v.after_sha256 === file.sha256
|
|
46
|
+
&& typeof v.diff === 'string';
|
|
47
|
+
}
|
|
48
|
+
export function agentComparisonMatches(v, workspace, campaign, change) {
|
|
49
|
+
return !!v && uuid(v.id) && v.workspace_id === workspace && v.baseline_id === campaign && v.change_id === change
|
|
50
|
+
&& uuid(v.actor_id) && uuid(v.request_key) && hex(v.request_digest) && hex(v.sha256)
|
|
51
|
+
&& ['queued', 'prepared', 'unavailable'].includes(v.state) && (v.current === null || typeof v.current === 'boolean')
|
|
52
|
+
&& [v.retained_count, v.additional_count, v.criterion_count].every(one => integer(one))
|
|
53
|
+
&& [v.repetitions, v.parallelism, v.trial_seconds].every(one => integer(one, 1))
|
|
54
|
+
&& [v.control_world_id, v.candidate_world_id].every(one => one === null || uuid(one))
|
|
55
|
+
&& (v.problem === null || typeof v.problem === 'string');
|
|
56
|
+
}
|
|
57
|
+
export function agentComparisonRequestMatches(v, workspace, campaign, change, actor, key) {
|
|
58
|
+
return sourceChangePageMatches(v, workspace, campaign, 1) && v.change_id === change && v.count <= 1
|
|
59
|
+
&& v.results.length === v.count && v.results.every(row => agentComparisonMatches(row, workspace, campaign, change)
|
|
60
|
+
&& row.actor_id === actor && row.request_key === key);
|
|
61
|
+
}
|
|
62
|
+
export function candidateSourceMatches(v, workspace, campaign, change) {
|
|
63
|
+
return !!v && v.schema === 'firedrill.agent-change-export.v1' && v.workspace_id === workspace && v.baseline_id === campaign
|
|
64
|
+
&& v.change_id === change && [v.source_id, v.world_id, v.agent_id, v.snapshot?.id].every(uuid)
|
|
65
|
+
&& [v.scope_sha256, v.draft_sha256, v.files_sha256, v.snapshot?.sha256].every(hex)
|
|
66
|
+
&& !!v.capacity && Object.keys(v.capacity).sort().join(',') === 'archive_bytes,directory_bytes,expanded_bytes,file_bytes,files'
|
|
67
|
+
&& Object.values(v.capacity).every(one => integer(one, 1)) && integer(v.snapshot.size, 1) && v.snapshot.size <= v.capacity.archive_bytes
|
|
68
|
+
&& typeof v.snapshot.generation === 'string' && /^[1-9][0-9]{0,30}$/.test(v.snapshot.generation)
|
|
69
|
+
&& integer(v.file_count, 1) && v.file_count <= v.capacity.files && integer(v.expanded_bytes) && v.expanded_bytes <= v.capacity.expanded_bytes
|
|
70
|
+
&& v.target_executed === false && v.vault_access_inherited === false;
|
|
71
|
+
}
|
|
72
|
+
export async function sourceMetadataDigest(value) {
|
|
73
|
+
const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(nativeMetadataCanonical(value)));
|
|
74
|
+
return Array.from(new Uint8Array(hash), one => one.toString(16).padStart(2, '0')).join('');
|
|
75
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const record = (value) => Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
2
|
+
const hash = (value) => typeof value === 'string' && /^[a-f0-9]{64}$/.test(value);
|
|
3
|
+
const fields = (value, names) => Object.keys(value).sort().join(',') === names.sort().join(',');
|
|
4
|
+
export function driverBasisMatches(value) {
|
|
5
|
+
return record(value) && fields(value, ['source_set_sha256', 'graph_sha256', 'configuration_sha256', 'world_revision'])
|
|
6
|
+
&& ['source_set_sha256', 'graph_sha256', 'configuration_sha256'].every(key => hash(value[key]))
|
|
7
|
+
&& typeof value.world_revision === 'string' && value.world_revision.length > 0 && value.world_revision.length <= 128;
|
|
8
|
+
}
|
|
9
|
+
export function executionDriverMatches(value) {
|
|
10
|
+
return record(value) && fields(value, ['schema', 'contract_sha256', 'input_scope_sha256', 'kind', 'requires_input', 'uses_participant_model', 'revision', 'basis', 'readiness',
|
|
11
|
+
...('scheduled_after_ms' in value ? ['scheduled_after_ms'] : [])])
|
|
12
|
+
&& value.schema === 'firedrill.agent-execution.v1' && hash(value.contract_sha256) && hash(value.input_scope_sha256)
|
|
13
|
+
&& typeof value.kind === 'string' && ['conversation', 'http_task', 'browser_workflow', 'adaptive_browser', 'desktop', 'process', 'event'].includes(value.kind)
|
|
14
|
+
&& value.requires_input === !['conversation', 'http_task'].includes(value.kind)
|
|
15
|
+
&& value.uses_participant_model === ['adaptive_browser', 'desktop'].includes(value.kind)
|
|
16
|
+
&& (value.scheduled_after_ms == null || value.kind === 'event' && Number.isSafeInteger(value.scheduled_after_ms)
|
|
17
|
+
&& value.scheduled_after_ms >= 0 && value.scheduled_after_ms < 30 * 86400 * 1000)
|
|
18
|
+
&& typeof value.revision === 'string' && /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/.test(value.revision)
|
|
19
|
+
&& driverBasisMatches(value.basis) && value.readiness === 'not_executed';
|
|
20
|
+
}
|
|
21
|
+
export function executionScheduleText(driver) {
|
|
22
|
+
if (driver.kind !== 'event' || driver.scheduled_after_ms == null)
|
|
23
|
+
return null;
|
|
24
|
+
if (driver.scheduled_after_ms === 0)
|
|
25
|
+
return 'Send the event without a scheduled delay.';
|
|
26
|
+
const seconds = driver.scheduled_after_ms / 1000;
|
|
27
|
+
const duration = seconds < 60 ? `${seconds.toLocaleString()} seconds`
|
|
28
|
+
: seconds < 3600 ? `${(seconds / 60).toLocaleString(undefined, { maximumFractionDigits: 2 })} minutes`
|
|
29
|
+
: `${(seconds / 3600).toLocaleString(undefined, { maximumFractionDigits: 2 })} hours`;
|
|
30
|
+
return `Wait ${duration} before sending the event. This delay uses real time and counts toward the drill time limit.`;
|
|
31
|
+
}
|
|
32
|
+
export function executionAuthorityMatches(value, driver) {
|
|
33
|
+
if (!driver?.requires_input)
|
|
34
|
+
return value === null;
|
|
35
|
+
return record(value) && fields(value, ['schema', 'contract_sha256', 'input_authorized', 'simulated_only', 'allowed_kind'])
|
|
36
|
+
&& value.schema === 'firedrill.agent-execution-authority.v1' && value.contract_sha256 === driver.contract_sha256
|
|
37
|
+
&& value.input_authorized === true && value.simulated_only === true && value.allowed_kind === driver.kind;
|
|
38
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const uuid = /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/, hash = /^[a-f0-9]{64}$/;
|
|
2
|
+
export function applicationCheckpointMatches(value, world, selected = {}) {
|
|
3
|
+
return !!value && uuid.test(value.id) && value.world_id === world && uuid.test(value.session_id)
|
|
4
|
+
&& (selected.session === undefined || value.session_id === selected.session) && (selected.id === undefined || value.id === selected.id)
|
|
5
|
+
&& (selected.key === undefined || value.request_key === selected.key) && typeof value.request_key === 'string' && value.request_key.length > 0
|
|
6
|
+
&& ['pending', 'retained', 'unavailable'].includes(value.state) && typeof value.available === 'boolean' && value.controlled_services_included === false
|
|
7
|
+
&& typeof value.name === 'string' && value.name.length > 0 && value.name.length <= 120 && Number.isFinite(Date.parse(value.created_at))
|
|
8
|
+
&& (value.captured_at === null || Number.isFinite(Date.parse(value.captured_at))) && Array.isArray(value.components) && value.components.length <= 1000
|
|
9
|
+
&& value.components.every(one => !!one && typeof one.name === 'string' && one.name.length > 0
|
|
10
|
+
&& ['application_memory', 'database', 'files', 'queue_cursor', 'conversation', 'scheduled_jobs'].includes(one.kind)
|
|
11
|
+
&& ['application_consistent', 'crash_consistent'].includes(one.consistency))
|
|
12
|
+
&& Array.isArray(value.excluded) && value.excluded.length <= 1000 && value.excluded.every(one => typeof one === 'string' && one.length > 0 && one.length <= 256)
|
|
13
|
+
&& (value.event_watermark === null || typeof value.event_watermark === 'string' && value.event_watermark.length > 0 && value.event_watermark.length <= 256)
|
|
14
|
+
&& (!value.available || value.state === 'retained' && value.captured_at !== null && value.components.length > 0 && value.excluded.length > 0);
|
|
15
|
+
}
|
|
16
|
+
export function applicationStateReference(value) {
|
|
17
|
+
const row = value;
|
|
18
|
+
return !!row && typeof row === 'object' && !Array.isArray(row) && Object.keys(row).sort().join(',') === 'archive_id,checkpoint_id,checkpoint_session_id,components,continuity,controlled_services_included,driver_digest,event_watermark,excluded,generation,sha256,size'
|
|
19
|
+
&& [row.checkpoint_id, row.checkpoint_session_id, row.archive_id].every(one => typeof one === 'string' && uuid.test(one))
|
|
20
|
+
&& [row.sha256, row.driver_digest].every(one => typeof one === 'string' && hash.test(one)) && Number.isSafeInteger(row.size) && row.size > 0 && row.size <= 8 * 1024 ** 2
|
|
21
|
+
&& typeof row.generation === 'string' && /^[1-9][0-9]{0,30}$/.test(row.generation) && row.controlled_services_included === false && row.continuity === 'application_supported_new_process'
|
|
22
|
+
&& typeof row.event_watermark === 'string' && row.event_watermark.length > 0 && row.event_watermark.length <= 256 && !/[\u0000-\u001f\u007f]/.test(row.event_watermark)
|
|
23
|
+
&& Array.isArray(row.components) && row.components.length > 0 && row.components.length <= 1000 && row.components.every(one => !!one && typeof one.name === 'string' && one.name.length > 0
|
|
24
|
+
&& ['application_memory', 'database', 'files', 'queue_cursor', 'conversation', 'scheduled_jobs'].includes(one.kind) && ['application_consistent', 'crash_consistent'].includes(one.consistency))
|
|
25
|
+
&& Array.isArray(row.excluded) && row.excluded.length > 0 && row.excluded.length <= 1000 && row.excluded.every(one => typeof one === 'string' && one.length > 0 && one.length <= 256);
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { memoryProbeMatches } from './revision-contracts.js';
|
|
2
|
+
export function scoreCohortMatches(actual, expected) {
|
|
3
|
+
return actual.assessment_id === expected.assessment_id
|
|
4
|
+
&& (expected.identity === undefined || actual.identity === expected.identity);
|
|
5
|
+
}
|
|
6
|
+
export function checkpointMatches(page, assessment, index, expected) {
|
|
7
|
+
const probe = page.cohort.memory.probes[index];
|
|
8
|
+
return page.cohort.assessment_id === assessment && !!probe && memoryProbeMatches(page.probe, probe)
|
|
9
|
+
&& (!expected || page.cohort.scenario_id === expected.scenario_id && page.cohort.rubric_digest === expected.rubric_digest
|
|
10
|
+
&& page.cohort.model === expected.model && page.cohort.requested_model === expected.requested_model);
|
|
11
|
+
}
|
|
12
|
+
export function styleCohortMatches(actual, expected) {
|
|
13
|
+
return actual.assessment_id === expected.assessment_id && (expected.identity === undefined || actual.identity === expected.identity)
|
|
14
|
+
&& (expected.parser === undefined || actual.parser === expected.parser);
|
|
15
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const uuid = (value) => typeof value === 'string'
|
|
2
|
+
&& /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(value);
|
|
3
|
+
const keyPattern = /^[A-Za-z0-9][A-Za-z0-9:._-]{0,127}$/;
|
|
4
|
+
function checkpointMatches(value, partial) {
|
|
5
|
+
return value === null || !!value && partial === true && value.schema === 'firedrill.assessment-checkpoint.v1'
|
|
6
|
+
&& /^[a-f0-9]{64}$/.test(value.event_id) && uuid(value.attempt_id) && uuid(value.stream_id)
|
|
7
|
+
&& Number.isSafeInteger(value.attempt_number) && value.attempt_number >= 1
|
|
8
|
+
&& Number.isSafeInteger(value.turn) && value.turn >= 2 && value.turn <= 100000
|
|
9
|
+
&& Number.isFinite(Date.parse(value.observed_at)) && (value.artifact_ceiling === null
|
|
10
|
+
|| Number.isSafeInteger(value.artifact_ceiling) && value.artifact_ceiling >= 0 && value.artifact_ceiling <= 9999999999)
|
|
11
|
+
&& (value.world_event_key === undefined && value.world_receipt_event_id === undefined
|
|
12
|
+
|| typeof value.world_event_key === 'string' && /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(value.world_event_key)
|
|
13
|
+
&& /^[a-f0-9]{64}$/.test(value.world_receipt_event_id ?? ''));
|
|
14
|
+
}
|
|
15
|
+
export function assessmentMatches(row, campaign, execution, id) {
|
|
16
|
+
if (!row || !uuid(row.id) || id !== undefined && row.id !== id || row.campaign_id !== campaign
|
|
17
|
+
|| row.execution_id !== execution || !uuid(row.agent_id) || row.provider !== 'Firedrill'
|
|
18
|
+
|| !checkpointMatches(row.checkpoint, row.partial_execution))
|
|
19
|
+
return false;
|
|
20
|
+
if (row.state === 'unavailable')
|
|
21
|
+
return row.result === null && row.evidence_count === null
|
|
22
|
+
&& Object.keys(row.rubric).length === 0;
|
|
23
|
+
if (!Array.isArray(row.rubric?.levels) || row.rubric.levels.length < 2 || row.rubric.levels.length > 10
|
|
24
|
+
|| !Number.isSafeInteger(row.evidence_count) || row.evidence_count < 0)
|
|
25
|
+
return false;
|
|
26
|
+
if (row.result === null)
|
|
27
|
+
return row.state !== 'succeeded';
|
|
28
|
+
return !!row.model && ['succeeded', 'not_assessable', 'not_applicable'].includes(row.state)
|
|
29
|
+
&& row.result.status === (row.state === 'succeeded' ? 'assessable' : row.state)
|
|
30
|
+
&& row.result.levels.length === row.rubric.levels.length
|
|
31
|
+
&& row.result.levels.every((level, index) => level === row.rubric.levels[index])
|
|
32
|
+
&& explanationMatches(row.result.explanation)
|
|
33
|
+
&& (row.result.status === 'assessable' ? typeof row.result.score === 'number' && Number.isFinite(row.result.score)
|
|
34
|
+
&& row.result.score >= 0 && row.result.score <= row.result.levels.length - 1 : row.result.score === null);
|
|
35
|
+
}
|
|
36
|
+
function explanationMatches(value) {
|
|
37
|
+
return !!value && ['queued', 'submitted', 'succeeded', 'failed', 'unknown', 'unavailable'].includes(value.state)
|
|
38
|
+
&& value.attribution === 'evidence_synthesis' && typeof value.requested_model === 'string'
|
|
39
|
+
&& Array.isArray(value.observations) && value.observations.length <= 4 && typeof value.limitation === 'string'
|
|
40
|
+
&& value.observations.every(item => typeof item.text === 'string' && item.text.length > 0 && item.text.length <= 1200
|
|
41
|
+
&& Array.isArray(item.evidence) && item.evidence.length >= 1 && item.evidence.length <= 4
|
|
42
|
+
&& item.evidence.every(ref => ['message', 'action', 'state'].includes(ref.kind) && uuid(ref.id) && uuid(ref.evidence_id)
|
|
43
|
+
&& (ref.kind === 'state' && ref.position === null || typeof ref.position === 'number'
|
|
44
|
+
&& Number.isSafeInteger(ref.position) && ref.position >= 0)
|
|
45
|
+
&& typeof ref.quote === 'string' && ref.quote.length > 0 && ref.quote.length <= 280)
|
|
46
|
+
&& Array.isArray(item.policies) && item.policies.length <= 4 && item.policies.every(ref => uuid(ref.revision_id)
|
|
47
|
+
&& /^p[0-9]{1,11}$/.test(ref.paragraph_id) && typeof ref.quote === 'string' && ref.quote.length > 0 && ref.quote.length <= 280))
|
|
48
|
+
&& (value.state !== 'succeeded' || typeof value.model === 'string' && value.model.length > 0
|
|
49
|
+
&& /^[a-f0-9]{64}$/.test(value.input_sha256 ?? '') && /^[a-f0-9]{64}$/.test(value.response_sha256 ?? '')
|
|
50
|
+
&& (value.observations.length > 0 || value.limitation.length > 0));
|
|
51
|
+
}
|
|
52
|
+
export function assessmentPageMatches(page, campaign, execution) {
|
|
53
|
+
return !!page && Array.isArray(page.results) && page.results.every(row => row.campaign_id === campaign
|
|
54
|
+
&& row.execution_id === execution && uuid(row.id) && checkpointMatches(row.checkpoint, row.partial_execution));
|
|
55
|
+
}
|
|
56
|
+
/** Original actor/key acceptance only. Never resubmit a target or evaluator. */
|
|
57
|
+
export function assessmentRequestMatches(row, scope, key) {
|
|
58
|
+
return !!row && row.schema === 'firedrill.assessment-request-receipt.v1' && row.actor_id === scope.actor
|
|
59
|
+
&& row.workspace_id === scope.workspace && row.campaign_id === scope.campaign && row.execution_id === scope.execution
|
|
60
|
+
&& typeof row.request_key === 'string' && keyPattern.test(row.request_key) && (key === undefined || row.request_key === key)
|
|
61
|
+
&& ['accepted', 'withdrawn', 'not_received'].includes(row.state) && typeof row.resource_available === 'boolean'
|
|
62
|
+
&& (row.resource_available ? row.state === 'accepted' && uuid(row.assessment_id) && typeof row.assessment_state === 'string'
|
|
63
|
+
: row.assessment_id === null && row.assessment_state === null);
|
|
64
|
+
}
|
|
65
|
+
export function assessmentAcceptanceMatches(receipt, row, scope, key) {
|
|
66
|
+
return assessmentRequestMatches(receipt, scope, key) && assessmentMatches(row, scope.campaign, scope.execution)
|
|
67
|
+
&& receipt.state === 'accepted' && receipt.resource_available && receipt.assessment_id === row.id;
|
|
68
|
+
}
|
|
69
|
+
export function assessmentEvidenceMatches(row, expected) {
|
|
70
|
+
const position = expected.kind === 'state' ? row.sequence : row.position;
|
|
71
|
+
return uuid(row.id) && uuid(row.evidence_id) && row.id === expected.id && row.evidence_id === expected.evidence_id
|
|
72
|
+
&& position === expected.position && (expected.kind === 'state' && position === null
|
|
73
|
+
|| typeof position === 'number' && Number.isSafeInteger(position) && position >= 0);
|
|
74
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const uuid = (v) => typeof v === 'string' && /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(v);
|
|
2
|
+
const date = (v) => typeof v === 'string' && Number.isFinite(Date.parse(v));
|
|
3
|
+
const integer = (v) => typeof v === 'number' && Number.isSafeInteger(v);
|
|
4
|
+
const count = (v) => integer(v) && v >= 0;
|
|
5
|
+
const text = (v, limit = 128) => typeof v === 'string' && v.length <= limit && !/[\u0000-\u001f\u007f]/.test(v);
|
|
6
|
+
const invoiceId = (v) => typeof v === 'string' && /^in_[A-Za-z0-9_]{1,120}$/.test(v);
|
|
7
|
+
const planOffers = ['starter_monthly', 'starter_annual', 'team_monthly', 'team_annual', 'scale_monthly', 'scale_annual'];
|
|
8
|
+
export function billingPurchaseSelectionMatches(kind, offer, interval) {
|
|
9
|
+
const plan = (offer === 'starter' || offer === 'team' || offer === 'scale') && (interval === 'monthly' || interval === 'annual');
|
|
10
|
+
return kind === 'subscription' ? plan : kind === 'portal' ? (offer === '' && interval === '' || plan)
|
|
11
|
+
: false;
|
|
12
|
+
}
|
|
13
|
+
export function billingCommerceRead(value, matches) {
|
|
14
|
+
if (!matches)
|
|
15
|
+
throw new Error('The payment response could not be confirmed for this organization and original request. Inspect its saved request before continuing.');
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
function scope(v, workspace, organization) {
|
|
19
|
+
return !!v && v.selected_workspace_id === workspace && uuid(v.organization_id) && uuid(v.account_id)
|
|
20
|
+
&& (!organization || v.organization_id === organization);
|
|
21
|
+
}
|
|
22
|
+
export function billingOptionsMatch(v, workspace, actor, organization) {
|
|
23
|
+
if (!scope(v, workspace, organization) || v.actor_id !== actor || typeof v.available !== 'boolean' || typeof v.portal !== 'boolean'
|
|
24
|
+
|| !Array.isArray(v.plans) || !Array.isArray(v.changes) || !Array.isArray(v.packs) || v.plans.length > 100 || v.packs.length > 100 || v.changes.length > 6
|
|
25
|
+
|| ![...v.plans, ...v.packs].every(one => typeof one === 'string' && /^[a-z0-9_]{1,32}$/.test(one))
|
|
26
|
+
|| !v.changes.every(one => typeof one === 'string' && planOffers.includes(one))
|
|
27
|
+
|| new Set(v.plans).size !== v.plans.length || new Set(v.packs).size !== v.packs.length || new Set(v.changes).size !== v.changes.length
|
|
28
|
+
|| !v.available && (v.portal || v.plans.length > 0 || v.packs.length > 0 || v.changes.length > 0))
|
|
29
|
+
return false;
|
|
30
|
+
const row = v.subscription;
|
|
31
|
+
if (v.changes.length && (!row || row.cancel_at_period_end || row.scheduled_change || v.changes.some(one => one === `${row.plan}_${row.interval}`)))
|
|
32
|
+
return false;
|
|
33
|
+
return row === null || !!row && text(row.plan, 24) && text(row.interval, 16) && text(row.status, 24)
|
|
34
|
+
&& [row.period_start, row.period_end, row.observed_at].every(date) && Date.parse(row.period_end) > Date.parse(row.period_start)
|
|
35
|
+
&& typeof row.cancel_at_period_end === 'boolean' && (row.scheduled_change === null || !!row.scheduled_change
|
|
36
|
+
&& text(row.scheduled_change.plan, 24) && text(row.scheduled_change.interval, 16) && date(row.scheduled_change.at));
|
|
37
|
+
}
|
|
38
|
+
export function billingPurchaseMatches(v, workspace, selected = {}) {
|
|
39
|
+
const denomination = !!v && (v.denomination === null || typeof v.denomination === 'string'
|
|
40
|
+
&& /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,31}$/.test(v.denomination));
|
|
41
|
+
const knownUnit = !!v && typeof v.denomination === 'string' && denomination
|
|
42
|
+
&& integer(v.credit_scale) && v.credit_scale >= 1 && /^10*$/.test(String(v.credit_scale));
|
|
43
|
+
const plainPortal = !!v && v.kind === 'portal' && v.amount_cents === 0 && v.units === 0
|
|
44
|
+
&& v.offer === '' && v.interval === '' && v.denomination === null && v.credit_scale === null;
|
|
45
|
+
if (!scope(v, workspace, selected.organization) || !uuid(v.id) || selected.id && v.id !== selected.id || !uuid(v.actor_id)
|
|
46
|
+
|| v.workspace_id !== null && !uuid(v.workspace_id) || !text(v.request_key) || !v.request_key
|
|
47
|
+
|| !['subscription', 'portal'].includes(v.kind) || !text(v.offer, 32) || !text(v.interval, 16)
|
|
48
|
+
|| !billingPurchaseSelectionMatches(v.kind, v.offer, v.interval)
|
|
49
|
+
|| v.kind === 'portal' && (v.units !== 0 || v.offer === '' && v.interval === '' && v.amount_cents !== 0)
|
|
50
|
+
|| ![v.amount_cents, v.units].every(count) || v.currency !== 'usd' || !text(v.state, 24)
|
|
51
|
+
|| !denomination || !(knownUnit || v.credit_scale === null && (v.url === null || plainPortal))
|
|
52
|
+
|| v.request_state !== null && !text(v.request_state, 24) || !date(v.created_at)
|
|
53
|
+
|| v.expires_at !== null && !date(v.expires_at) || v.message !== undefined && !text(v.message, 512))
|
|
54
|
+
return false;
|
|
55
|
+
if (v.url !== null) {
|
|
56
|
+
try {
|
|
57
|
+
const link = new URL(v.url);
|
|
58
|
+
if (link.protocol !== 'https:' || link.host !== (v.kind === 'portal' ? 'billing.stripe.com' : 'checkout.stripe.com')
|
|
59
|
+
|| link.username || link.password || !['awaiting_payment', 'portal_ready'].includes(v.state) || v.request_state !== 'ready' || !v.expires_at)
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const original = selected.original;
|
|
67
|
+
return (!original || v.workspace_id === workspace && v.request_key === original.key && v.kind === original.kind && v.offer === original.offer && v.interval === original.interval)
|
|
68
|
+
&& (!selected.actor || v.actor_id === selected.actor);
|
|
69
|
+
}
|
|
70
|
+
export function billingPurchaseRequestMatches(v, workspace, actor, key, original, id, organization) {
|
|
71
|
+
if (!scope(v, workspace, organization) || v.actor_id !== actor || v.request_key !== key || !uuid(key) || typeof v.requested_by_me !== 'boolean')
|
|
72
|
+
return false;
|
|
73
|
+
if (v.state === 'not_received')
|
|
74
|
+
return !id && !v.requested_by_me && v.purchase === null;
|
|
75
|
+
return v.state === 'received' && v.requested_by_me && !!v.purchase && v.purchase.account_id === v.account_id
|
|
76
|
+
&& v.purchase.request_key === key && v.purchase.workspace_id === workspace
|
|
77
|
+
&& billingPurchaseMatches(v.purchase, workspace, { id, organization: v.organization_id, actor, original });
|
|
78
|
+
}
|
|
79
|
+
function page(v, workspace, number, organization) {
|
|
80
|
+
return scope(v, workspace, organization) && v.page === number && count(v.count) && count(v.page_size) && v.page_size >= 1 && v.page_size <= 100
|
|
81
|
+
&& Array.isArray(v.results) && v.results.length <= v.page_size && new Set(v.results.map(one => one.id)).size === v.results.length;
|
|
82
|
+
}
|
|
83
|
+
export function billingPurchasesMatch(v, workspace, status = '', number = 1, organization) {
|
|
84
|
+
return page(v, workspace, number, organization) && v.status === status && v.results.every(one => one.account_id === v.account_id && one.url === null
|
|
85
|
+
&& billingPurchaseMatches(one, workspace, { organization: v.organization_id }) && (!status || status === effectivePurchaseState(one)));
|
|
86
|
+
}
|
|
87
|
+
export function effectivePurchaseState(v) {
|
|
88
|
+
return !['paid', 'reversed'].includes(v.state) && ['uncertain', 'failed', 'reconciliation_required'].includes(v.request_state ?? '') ? v.request_state : v.state;
|
|
89
|
+
}
|
|
90
|
+
export function billingInvoiceMatches(v, workspace, id, organization) {
|
|
91
|
+
return scope(v, workspace, organization) && invoiceId(v.id) && (!id || v.id === id) && text(v.status, 24) && text(v.reconciliation, 24)
|
|
92
|
+
&& [v.subtotal_cents, v.total_cents].every(integer) && [v.paid_cents, v.discount_cents].every(count) && v.currency === 'usd'
|
|
93
|
+
&& date(v.created_at) && date(v.updated_at) && (v.paid_at === null || date(v.paid_at))
|
|
94
|
+
&& [v.plan, v.interval, v.payment_state].every(one => one === null || text(one, 24))
|
|
95
|
+
&& (v.service_starts_at === null && v.service_ends_at === null || date(v.service_starts_at) && date(v.service_ends_at)
|
|
96
|
+
&& Date.parse(v.service_ends_at) > Date.parse(v.service_starts_at));
|
|
97
|
+
}
|
|
98
|
+
export function billingInvoicesMatch(v, workspace, status = '', number = 1, organization) {
|
|
99
|
+
return page(v, workspace, number, organization) && v.status === status && v.results.every(one => one.account_id === v.account_id
|
|
100
|
+
&& billingInvoiceMatches(one, workspace, undefined, v.organization_id) && (!status || one.status === status));
|
|
101
|
+
}
|
|
102
|
+
export function billingInvoiceLinesMatch(v, workspace, id, number = 1, organization) {
|
|
103
|
+
return page(v, workspace, number, organization) && v.invoice_id === id && invoiceId(id) && uuid(v.observation_id)
|
|
104
|
+
&& typeof v.collection_complete === 'boolean' && text(v.reconciliation, 24) && v.results.every(one => /^il_[A-Za-z0-9_]{1,120}$/.test(one.id)
|
|
105
|
+
&& text(one.plan, 24) && text(one.interval, 16) && integer(one.amount_cents) && one.currency === 'usd' && typeof one.prorated === 'boolean'
|
|
106
|
+
&& date(one.service_starts_at) && date(one.service_ends_at) && Date.parse(one.service_ends_at) > Date.parse(one.service_starts_at));
|
|
107
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const uuid = (v) => typeof v === 'string' && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
|
|
2
|
+
const count = (v, min = 0) => typeof v === 'number' && Number.isSafeInteger(v) && v >= min;
|
|
3
|
+
const date = (v) => typeof v === 'string' && Number.isFinite(Date.parse(v));
|
|
4
|
+
const denomination = (v) => typeof v === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,31}$/.test(v);
|
|
5
|
+
const sources = ['included', 'purchased', 'sponsored', 'adjustment'];
|
|
6
|
+
export function creditUnitMatches(value, nullable = false) {
|
|
7
|
+
return !!value && (nullable && value.denomination === null && value.credit_scale === null
|
|
8
|
+
|| denomination(value.denomination) && count(value.credit_scale, 1));
|
|
9
|
+
}
|
|
10
|
+
export function billingWalletRead(value, matches) {
|
|
11
|
+
if (!matches)
|
|
12
|
+
throw new Error('The billing response did not match this workspace or organization. Reload Billing before continuing.');
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function metadataMatches(v, account) {
|
|
16
|
+
return !!v && uuid(v.account_id) && (!account || v.account_id === account) && ['free', 'starter', 'team', 'scale', 'enterprise'].includes(v.plan)
|
|
17
|
+
&& typeof v.subscription_state === 'string' && count(v.concurrency, 1) && typeof v.cancel_at_period_end === 'boolean'
|
|
18
|
+
&& [v.next_allocation_at, v.paid_through, v.enterprise_until].every(one => one === null || date(one));
|
|
19
|
+
}
|
|
20
|
+
export function billingBalanceMatches(v, account) {
|
|
21
|
+
return metadataMatches(v, account) && [v.available, v.reserved, v.debt].every(one => count(one))
|
|
22
|
+
&& creditUnitMatches(v) && typeof v.version === 'string' && !!v.version && typeof v.payment_review_required === 'boolean'
|
|
23
|
+
&& !!v.by_source && !Array.isArray(v.by_source) && Object.entries(v.by_source).every(([key, units]) => sources.includes(key) && count(units))
|
|
24
|
+
&& Object.values(v.by_source).reduce((sum, one) => sum + one, 0) === v.available;
|
|
25
|
+
}
|
|
26
|
+
export function billingSummaryMatches(v, workspace, actor, organization) {
|
|
27
|
+
if (!metadataMatches(v) || v.workspace_id !== workspace || v.actor_id !== actor || !uuid(v.organization_id)
|
|
28
|
+
|| organization && v.organization_id !== organization || typeof v.organization_name !== 'string'
|
|
29
|
+
|| typeof v.can_manage !== 'boolean' || typeof v.can_redeem !== 'boolean')
|
|
30
|
+
return false;
|
|
31
|
+
const catalog = v.catalog;
|
|
32
|
+
return !!catalog && typeof catalog.version === 'string' && catalog.currency === 'usd' && catalog.unit === 'Resource credits'
|
|
33
|
+
&& (catalog.denomination === null && catalog.credit_scale === null || denomination(catalog.denomination) && count(catalog.credit_scale, 1))
|
|
34
|
+
&& catalog.included_rollover === false && catalog.purchased_units_expire === false
|
|
35
|
+
&& Array.isArray(catalog.plans) && catalog.plans.length > 0 && catalog.plans.length <= 100
|
|
36
|
+
&& catalog.plans.every(plan => typeof plan.name === 'string' && ['free', 'starter', 'team', 'scale', 'enterprise'].includes(plan.key)
|
|
37
|
+
&& [plan.monthly_cents, plan.annual_cents, plan.monthly_units].every(value => value === null || count(value))
|
|
38
|
+
&& (plan.concurrency === null || count(plan.concurrency, 1)) && typeof plan.topups === 'boolean')
|
|
39
|
+
&& catalog.plans.some(plan => plan.key === v.plan) && new Set(catalog.plans.map(one => one.key)).size === catalog.plans.length
|
|
40
|
+
&& Array.isArray(catalog.packs) && catalog.packs.length <= 100
|
|
41
|
+
&& catalog.packs.every(pack => typeof pack.key === 'string' && count(pack.units, 1) && count(pack.amount_cents, 1))
|
|
42
|
+
&& new Set(catalog.packs.map(one => one.key)).size === catalog.packs.length;
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const id = (value) => typeof value === 'string' && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(value);
|
|
2
|
+
const date = (value) => value === null || typeof value === 'string' && Number.isFinite(Date.parse(value));
|
|
3
|
+
const decimal = (value) => typeof value === 'string' && /^(0|[1-9][0-9]{0,20})$/.test(value);
|
|
4
|
+
export function worldControlInputMatches(value) {
|
|
5
|
+
const one = value;
|
|
6
|
+
return !!one && typeof one === 'object' && Object.keys(one).sort().join(',') === 'action,expected_sequence,expected_watermark,next_scenario_id,previous_revision'
|
|
7
|
+
&& ['pause', 'resume', 'cancel_future', 'revise_future'].includes(one.action) && /^[a-f0-9]{64}$/.test(one.previous_revision)
|
|
8
|
+
&& typeof one.expected_watermark === 'string' && /^(0|[1-9][0-9]{0,5})$/.test(one.expected_watermark) && BigInt(one.expected_watermark) <= 100000n
|
|
9
|
+
&& Number.isSafeInteger(one.expected_sequence) && one.expected_sequence >= 0 && one.expected_sequence <= 100000
|
|
10
|
+
&& (one.action === 'revise_future' ? id(one.next_scenario_id) : one.next_scenario_id === null);
|
|
11
|
+
}
|
|
12
|
+
export function worldControlMatches(value, scope, original) {
|
|
13
|
+
if (!value || value.workspace_id !== scope.workspace || value.campaign_id !== scope.campaign || value.execution_id !== scope.execution
|
|
14
|
+
|| scope.actor !== undefined && value.actor_id !== scope.actor || !id(value.id) || !id(value.request_key) || !id(value.actor_id)
|
|
15
|
+
|| !/^[a-f0-9]{64}$/.test(value.command_sha256) || !Number.isSafeInteger(value.sequence) || value.sequence < 1
|
|
16
|
+
|| !['queued', 'publishing', 'unknown', 'observed', 'rejected', 'ended'].includes(value.state)
|
|
17
|
+
|| !['guest_report', 'customer_device'].includes(value.provenance)
|
|
18
|
+
|| value.problem !== undefined && value.problem !== null && typeof value.problem !== 'string'
|
|
19
|
+
|| !worldControlInputMatches({ action: value.action, previous_revision: value.previous_revision, expected_watermark: value.expected_watermark, expected_sequence: value.expected_sequence, next_scenario_id: value.next_scenario_id })
|
|
20
|
+
|| value.sequence !== value.expected_sequence + 1
|
|
21
|
+
|| ![value.not_after, value.created_at].every(at => typeof at === 'string' && date(at)) || ![value.publication_started_at, value.finished_at].every(date))
|
|
22
|
+
return false;
|
|
23
|
+
if (original && (original.key !== value.request_key || original.body && Object.keys(original.body).some(key => original.body[key] !== value[key])))
|
|
24
|
+
return false;
|
|
25
|
+
return value.result === null || !!value.result && ['observed', 'rejected', 'unknown'].includes(value.result.state)
|
|
26
|
+
&& typeof value.result.code === 'string' && /^[a-f0-9]{64}$/.test(value.result.revision)
|
|
27
|
+
&& Number.isSafeInteger(value.result.watermark) && value.result.watermark >= 0 && typeof value.result.observed_at === 'string' && date(value.result.observed_at);
|
|
28
|
+
}
|
|
29
|
+
export function runtimeRenewalPageMatches(value) {
|
|
30
|
+
return !!value && Number.isSafeInteger(value.count) && value.count >= 0 && Number.isSafeInteger(value.page) && value.page > 0
|
|
31
|
+
&& Number.isSafeInteger(value.page_size) && value.page_size >= 1 && value.page_size <= 100 && Array.isArray(value.results)
|
|
32
|
+
&& value.results.length <= value.page_size && value.results.every(one => id(one.id) && Number.isSafeInteger(one.sequence) && one.sequence > 0
|
|
33
|
+
&& ['publishing', 'observed', 'unknown', 'ended'].includes(one.state)
|
|
34
|
+
&& [one.requested_at, one.previous_expires_at, one.requested_expires_at].every(at => typeof at === 'string' && date(at))
|
|
35
|
+
&& [one.confirmed_expires_at, one.finished_at].every(date));
|
|
36
|
+
}
|
|
37
|
+
export function drillWorldPageMatches(value) {
|
|
38
|
+
const c = value?.continuity;
|
|
39
|
+
return !!c && Number.isSafeInteger(value.count) && value.count >= 0 && Number.isSafeInteger(value.page) && value.page > 0
|
|
40
|
+
&& Number.isSafeInteger(value.page_size) && value.page_size >= 1 && value.page_size <= 100
|
|
41
|
+
&& Array.isArray(value.results) && value.results.length <= value.page_size
|
|
42
|
+
&& c.scope === 'original_native_world_process' && c.target_clock_controlled === false
|
|
43
|
+
&& [null, 'continuous'].includes(c.mode) && ['not_started', 'running', 'finished', 'interrupted'].includes(c.state)
|
|
44
|
+
&& [c.started_at, c.deadline_at, c.finished_at, c.resource_deadline_at].every(date)
|
|
45
|
+
&& (c.elapsed_ms === null || decimal(c.elapsed_ms)) && !!c.events && typeof c.events === 'object'
|
|
46
|
+
&& (c.preparation_elapsed_ms === null || decimal(c.preparation_elapsed_ms))
|
|
47
|
+
&& ['controller_monotonic', 'service_wall_since_world_ready', 'not_observed'].includes(c.elapsed_basis)
|
|
48
|
+
&& ['active', 'paused', 'canceled'].includes(c.event_state)
|
|
49
|
+
&& (c.revision === null || /^[a-f0-9]{64}$/.test(c.revision)) && decimal(c.applied_watermark)
|
|
50
|
+
&& Number.isSafeInteger(c.control_sequence) && c.control_sequence >= 0 && c.control_sequence <= 100000
|
|
51
|
+
&& typeof c.control_pending === 'boolean'
|
|
52
|
+
&& Object.entries(c.events).every(([key, count]) => ['pending', 'applying', 'applied', 'unmet', 'uncertain', 'canceled'].includes(key) && Number.isSafeInteger(count) && count >= 0)
|
|
53
|
+
&& (c.next_event === null || typeof c.next_event?.key === 'string' && date(c.next_event.due_at))
|
|
54
|
+
&& (c.agent_process === null || !!c.agent_process && ['running', 'exited'].includes(c.agent_process.state)
|
|
55
|
+
&& typeof c.agent_process.source_entry_observed === 'boolean' && [c.agent_process.started_at, c.agent_process.finished_at, c.agent_process.source_entry_observed_at].every(date)
|
|
56
|
+
&& (c.agent_process.exit_code === null || Number.isSafeInteger(c.agent_process.exit_code)))
|
|
57
|
+
&& (c.interaction === null || !!c.interaction && c.interaction.basis === 'original_conversation_input_coordinator'
|
|
58
|
+
&& ['active', 'waiting_for_input', 'closed'].includes(c.interaction.state)
|
|
59
|
+
&& typeof c.interaction.observed_at === 'string' && date(c.interaction.observed_at)
|
|
60
|
+
&& Number.isSafeInteger(c.interaction.sequence) && c.interaction.sequence >= 1 && c.interaction.sequence <= 200001
|
|
61
|
+
&& id(c.interaction.message_stream_id) && [c.interaction.inputs, c.interaction.responses].every(one => Number.isSafeInteger(one) && one >= 0 && one <= 100000)
|
|
62
|
+
&& c.interaction.responses <= c.interaction.inputs && c.interaction.inputs <= c.interaction.responses + 1
|
|
63
|
+
&& (c.interaction.state !== 'active' || c.interaction.inputs === c.interaction.responses + 1)
|
|
64
|
+
&& (c.interaction.state !== 'waiting_for_input' || c.interaction.inputs > 0 && c.interaction.inputs === c.interaction.responses)
|
|
65
|
+
&& (id(c.interaction.request_id) || c.interaction.request_id === null && c.interaction.state === 'closed' && c.interaction.inputs === 0)
|
|
66
|
+
&& (c.interaction.cause_event_key === null || typeof c.interaction.cause_event_key === 'string' && /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(c.interaction.cause_event_key))
|
|
67
|
+
&& (c.interaction.state === 'closed' || c.state === 'running'))
|
|
68
|
+
&& value.results.every(one => id(one.id) && typeof one.key === 'string' && /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(one.key)
|
|
69
|
+
&& ['record', 'operation', 'ingress', 'message'].includes(one.kind)
|
|
70
|
+
&& Number.isSafeInteger(one.position) && one.position >= 0 && decimal(one.due_after_ms) && decimal(one.watermark)
|
|
71
|
+
&& ['pending', 'applying', 'applied', 'unmet', 'uncertain', 'canceled'].includes(one.state)
|
|
72
|
+
&& [one.due_at, one.intent_observed_at, one.receipt_observed_at].every(date)
|
|
73
|
+
&& [true, false, null].includes(one.condition_observed)
|
|
74
|
+
&& (one.result === null || one.kind !== 'record' && one.state === 'applied' && id(one.result.request_id)
|
|
75
|
+
&& !!one.result.observation && typeof one.result.observation === 'object' && !Array.isArray(one.result.observation)
|
|
76
|
+
&& Object.keys(one.result.observation).length <= 8
|
|
77
|
+
&& (one.result.evidence_id === null && one.result.download_path === null || id(one.result.evidence_id)
|
|
78
|
+
&& typeof one.result.download_path === 'string'
|
|
79
|
+
&& /^\/api\/workspaces\/[a-f0-9-]{36}\/campaigns\/[a-f0-9-]{36}\/trials\/[a-f0-9-]{36}\/evidence\/[a-f0-9-]{36}\/bytes$/.test(one.result.download_path))));
|
|
80
|
+
}
|